/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

// THIS FILE IS GENERATED BY ZAP

#pragma once

#import <Matter/Matter.h>

#include <cstdint>
#include <string>
#include <type_traits>

#include <app-common/zap-generated/cluster-objects.h>
#include <app/data-model/DecodableList.h>
#include <commands/clusters/ClusterCommandBridge.h>
#include <commands/clusters/ComplexArgument.h>
#include <commands/clusters/ReportCommandBridge.h>
#include <commands/clusters/WriteAttributeCommandBridge.h>

/*----------------------------------------------------------------------------*\
| Cluster Name                                                        |   ID   |
|---------------------------------------------------------------------+--------|
| Identify                                                            | 0x0003 |
| Groups                                                              | 0x0004 |
| Scenes                                                              | 0x0005 |
| OnOff                                                               | 0x0006 |
| OnOffSwitchConfiguration                                            | 0x0007 |
| LevelControl                                                        | 0x0008 |
| BinaryInputBasic                                                    | 0x000F |
| PulseWidthModulation                                                | 0x001C |
| Descriptor                                                          | 0x001D |
| Binding                                                             | 0x001E |
| AccessControl                                                       | 0x001F |
| Actions                                                             | 0x0025 |
| BasicInformation                                                    | 0x0028 |
| OtaSoftwareUpdateProvider                                           | 0x0029 |
| OtaSoftwareUpdateRequestor                                          | 0x002A |
| LocalizationConfiguration                                           | 0x002B |
| TimeFormatLocalization                                              | 0x002C |
| UnitLocalization                                                    | 0x002D |
| PowerSourceConfiguration                                            | 0x002E |
| PowerSource                                                         | 0x002F |
| GeneralCommissioning                                                | 0x0030 |
| NetworkCommissioning                                                | 0x0031 |
| DiagnosticLogs                                                      | 0x0032 |
| GeneralDiagnostics                                                  | 0x0033 |
| SoftwareDiagnostics                                                 | 0x0034 |
| ThreadNetworkDiagnostics                                            | 0x0035 |
| WiFiNetworkDiagnostics                                              | 0x0036 |
| EthernetNetworkDiagnostics                                          | 0x0037 |
| TimeSynchronization                                                 | 0x0038 |
| BridgedDeviceBasicInformation                                       | 0x0039 |
| Switch                                                              | 0x003B |
| AdministratorCommissioning                                          | 0x003C |
| OperationalCredentials                                              | 0x003E |
| GroupKeyManagement                                                  | 0x003F |
| FixedLabel                                                          | 0x0040 |
| UserLabel                                                           | 0x0041 |
| ProxyConfiguration                                                  | 0x0042 |
| ProxyDiscovery                                                      | 0x0043 |
| ProxyValid                                                          | 0x0044 |
| BooleanState                                                        | 0x0045 |
| ModeSelect                                                          | 0x0050 |
| HepaFilterMonitoring                                                | 0x0071 |
| ActivatedCarbonFilterMonitoring                                     | 0x0072 |
| CeramicFilterMonitoring                                             | 0x0073 |
| ElectrostaticFilterMonitoring                                       | 0x0074 |
| UvFilterMonitoring                                                  | 0x0075 |
| IonizingFilterMonitoring                                            | 0x0076 |
| ZeoliteFilterMonitoring                                             | 0x0077 |
| OzoneFilterMonitoring                                               | 0x0078 |
| WaterTankMonitoring                                                 | 0x0079 |
| FuelTankMonitoring                                                  | 0x007A |
| InkCartridgeMonitoring                                              | 0x007B |
| TonerCartridgeMonitoring                                            | 0x007C |
| DoorLock                                                            | 0x0101 |
| WindowCovering                                                      | 0x0102 |
| BarrierControl                                                      | 0x0103 |
| PumpConfigurationAndControl                                         | 0x0200 |
| Thermostat                                                          | 0x0201 |
| FanControl                                                          | 0x0202 |
| ThermostatUserInterfaceConfiguration                                | 0x0204 |
| ColorControl                                                        | 0x0300 |
| BallastConfiguration                                                | 0x0301 |
| IlluminanceMeasurement                                              | 0x0400 |
| TemperatureMeasurement                                              | 0x0402 |
| PressureMeasurement                                                 | 0x0403 |
| FlowMeasurement                                                     | 0x0404 |
| RelativeHumidityMeasurement                                         | 0x0405 |
| OccupancySensing                                                    | 0x0406 |
| WakeOnLan                                                           | 0x0503 |
| Channel                                                             | 0x0504 |
| TargetNavigator                                                     | 0x0505 |
| MediaPlayback                                                       | 0x0506 |
| MediaInput                                                          | 0x0507 |
| LowPower                                                            | 0x0508 |
| KeypadInput                                                         | 0x0509 |
| ContentLauncher                                                     | 0x050A |
| AudioOutput                                                         | 0x050B |
| ApplicationLauncher                                                 | 0x050C |
| ApplicationBasic                                                    | 0x050D |
| AccountLogin                                                        | 0x050E |
| ElectricalMeasurement                                               | 0x0B04 |
| ClientMonitoring                                                    | 0x1046 |
| UnitTesting                                                         | 0xFFF1FC05|
| FaultInjection                                                      | 0xFFF1FC06|
\*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*\
| Cluster Identify                                                    | 0x0003 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * Identify                                                          |   0x00 |
| * TriggerEffect                                                     |   0x40 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * IdentifyTime                                                      | 0x0000 |
| * IdentifyType                                                      | 0x0001 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command Identify
 */
class IdentifyIdentify : public ClusterCommand {
public:
    IdentifyIdentify()
        : ClusterCommand("identify")
    {
        AddArgument("IdentifyTime", 0, UINT16_MAX, &mRequest.identifyTime);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRIdentifyClusterIdentifyParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.identifyTime = [NSNumber numberWithUnsignedShort:mRequest.identifyTime];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster identifyWithParams:params
                             completion:^(NSError * _Nullable error) {
                                 responsesNeeded--;
                                 if (error != nil) {
                                     mError = error;
                                     LogNSError("Error", error);
                                 }
                                 if (responsesNeeded == 0) {
                                     SetCommandExitStatus(mError);
                                 }
                             }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Identify::Commands::Identify::Type mRequest;
};

/*
 * Command TriggerEffect
 */
class IdentifyTriggerEffect : public ClusterCommand {
public:
    IdentifyTriggerEffect()
        : ClusterCommand("trigger-effect")
    {
        AddArgument("EffectIdentifier", 0, UINT8_MAX, &mRequest.effectIdentifier);
        AddArgument("EffectVariant", 0, UINT8_MAX, &mRequest.effectVariant);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) command (0x00000040) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRIdentifyClusterTriggerEffectParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.effectIdentifier = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.effectIdentifier)];
        params.effectVariant = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.effectVariant)];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster triggerEffectWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Identify::Commands::TriggerEffect::Type mRequest;
};

/*
 * Attribute IdentifyTime
 */
class ReadIdentifyIdentifyTime : public ReadAttribute {
public:
    ReadIdentifyIdentifyTime()
        : ReadAttribute("identify-time")
    {
    }

    ~ReadIdentifyIdentifyTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeIdentifyTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.IdentifyTime response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify IdentifyTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteIdentifyIdentifyTime : public WriteAttribute {
public:
    WriteIdentifyIdentifyTime()
        : WriteAttribute("identify-time")
    {
        AddArgument("attr-name", "identify-time");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteIdentifyIdentifyTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeIdentifyTimeWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("Identify IdentifyTime write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeIdentifyIdentifyTime : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyIdentifyTime()
        : SubscribeAttribute("identify-time")
    {
    }

    ~SubscribeAttributeIdentifyIdentifyTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeIdentifyTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.IdentifyTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute IdentifyType
 */
class ReadIdentifyIdentifyType : public ReadAttribute {
public:
    ReadIdentifyIdentifyType()
        : ReadAttribute("identify-type")
    {
    }

    ~ReadIdentifyIdentifyType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeIdentifyTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.IdentifyType response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify IdentifyType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIdentifyIdentifyType : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyIdentifyType()
        : SubscribeAttribute("identify-type")
    {
    }

    ~SubscribeAttributeIdentifyIdentifyType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeIdentifyTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.IdentifyType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadIdentifyGeneratedCommandList : public ReadAttribute {
public:
    ReadIdentifyGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadIdentifyGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIdentifyGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeIdentifyGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadIdentifyAcceptedCommandList : public ReadAttribute {
public:
    ReadIdentifyAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadIdentifyAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIdentifyAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeIdentifyAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadIdentifyAttributeList : public ReadAttribute {
public:
    ReadIdentifyAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadIdentifyAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIdentifyAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeIdentifyAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadIdentifyFeatureMap : public ReadAttribute {
public:
    ReadIdentifyFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadIdentifyFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIdentifyFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeIdentifyFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadIdentifyClusterRevision : public ReadAttribute {
public:
    ReadIdentifyClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadIdentifyClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIdentifyClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeIdentifyClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Groups                                                      | 0x0004 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * AddGroup                                                          |   0x00 |
| * ViewGroup                                                         |   0x01 |
| * GetGroupMembership                                                |   0x02 |
| * RemoveGroup                                                       |   0x03 |
| * RemoveAllGroups                                                   |   0x04 |
| * AddGroupIfIdentifying                                             |   0x05 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * NameSupport                                                       | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command AddGroup
 */
class GroupsAddGroup : public ClusterCommand {
public:
    GroupsAddGroup()
        : ClusterCommand("add-group")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("GroupName", &mRequest.groupName);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRGroupsClusterAddGroupParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.groupName = [[NSString alloc] initWithBytes:mRequest.groupName.data()
                                                    length:mRequest.groupName.size()
                                                  encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster addGroupWithParams:params
                             completion:^(MTRGroupsClusterAddGroupResponseParams * _Nullable values, NSError * _Nullable error) {
                                 NSLog(@"Values: %@", values);
                                 responsesNeeded--;
                                 if (error != nil) {
                                     mError = error;
                                     LogNSError("Error", error);
                                 }
                                 if (responsesNeeded == 0) {
                                     SetCommandExitStatus(mError);
                                 }
                             }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Groups::Commands::AddGroup::Type mRequest;
};

/*
 * Command ViewGroup
 */
class GroupsViewGroup : public ClusterCommand {
public:
    GroupsViewGroup()
        : ClusterCommand("view-group")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRGroupsClusterViewGroupParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster viewGroupWithParams:params
                              completion:^(MTRGroupsClusterViewGroupResponseParams * _Nullable values, NSError * _Nullable error) {
                                  NSLog(@"Values: %@", values);
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Groups::Commands::ViewGroup::Type mRequest;
};

/*
 * Command GetGroupMembership
 */
class GroupsGetGroupMembership : public ClusterCommand {
public:
    GroupsGetGroupMembership()
        : ClusterCommand("get-group-membership")
        , mComplex_GroupList(&mRequest.groupList)
    {
        AddArgument("GroupList", &mComplex_GroupList);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRGroupsClusterGetGroupMembershipParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.groupList) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithUnsignedShort:entry_0];
                [array_0 addObject:newElement_0];
            }
            params.groupList = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getGroupMembershipWithParams:params
                                       completion:^(MTRGroupsClusterGetGroupMembershipResponseParams * _Nullable values,
                                           NSError * _Nullable error) {
                                           NSLog(@"Values: %@", values);
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Groups::Commands::GetGroupMembership::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const chip::GroupId>> mComplex_GroupList;
};

/*
 * Command RemoveGroup
 */
class GroupsRemoveGroup : public ClusterCommand {
public:
    GroupsRemoveGroup()
        : ClusterCommand("remove-group")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRGroupsClusterRemoveGroupParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                removeGroupWithParams:params
                           completion:^(MTRGroupsClusterRemoveGroupResponseParams * _Nullable values, NSError * _Nullable error) {
                               NSLog(@"Values: %@", values);
                               responsesNeeded--;
                               if (error != nil) {
                                   mError = error;
                                   LogNSError("Error", error);
                               }
                               if (responsesNeeded == 0) {
                                   SetCommandExitStatus(mError);
                               }
                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Groups::Commands::RemoveGroup::Type mRequest;
};

/*
 * Command RemoveAllGroups
 */
class GroupsRemoveAllGroups : public ClusterCommand {
public:
    GroupsRemoveAllGroups()
        : ClusterCommand("remove-all-groups")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRGroupsClusterRemoveAllGroupsParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster removeAllGroupsWithParams:params
                                    completion:^(NSError * _Nullable error) {
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command AddGroupIfIdentifying
 */
class GroupsAddGroupIfIdentifying : public ClusterCommand {
public:
    GroupsAddGroupIfIdentifying()
        : ClusterCommand("add-group-if-identifying")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("GroupName", &mRequest.groupName);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRGroupsClusterAddGroupIfIdentifyingParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.groupName = [[NSString alloc] initWithBytes:mRequest.groupName.data()
                                                    length:mRequest.groupName.size()
                                                  encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster addGroupIfIdentifyingWithParams:params
                                          completion:^(NSError * _Nullable error) {
                                              responsesNeeded--;
                                              if (error != nil) {
                                                  mError = error;
                                                  LogNSError("Error", error);
                                              }
                                              if (responsesNeeded == 0) {
                                                  SetCommandExitStatus(mError);
                                              }
                                          }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Groups::Commands::AddGroupIfIdentifying::Type mRequest;
};

/*
 * Attribute NameSupport
 */
class ReadGroupsNameSupport : public ReadAttribute {
public:
    ReadGroupsNameSupport()
        : ReadAttribute("name-support")
    {
    }

    ~ReadGroupsNameSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNameSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Groups.NameSupport response %@", [value description]);
            if (error != nil) {
                LogNSError("Groups NameSupport read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupsNameSupport : public SubscribeAttribute {
public:
    SubscribeAttributeGroupsNameSupport()
        : SubscribeAttribute("name-support")
    {
    }

    ~SubscribeAttributeGroupsNameSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNameSupportWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Groups.NameSupport response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadGroupsGeneratedCommandList : public ReadAttribute {
public:
    ReadGroupsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadGroupsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Groups.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Groups GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeGroupsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Groups.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadGroupsAcceptedCommandList : public ReadAttribute {
public:
    ReadGroupsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadGroupsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Groups.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Groups AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeGroupsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Groups.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadGroupsAttributeList : public ReadAttribute {
public:
    ReadGroupsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadGroupsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Groups.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Groups AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeGroupsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Groups.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadGroupsFeatureMap : public ReadAttribute {
public:
    ReadGroupsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadGroupsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Groups.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Groups FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeGroupsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeGroupsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Groups.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadGroupsClusterRevision : public ReadAttribute {
public:
    ReadGroupsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadGroupsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Groups.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Groups ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeGroupsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeGroupsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Groups.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Scenes                                                      | 0x0005 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * AddScene                                                          |   0x00 |
| * ViewScene                                                         |   0x01 |
| * RemoveScene                                                       |   0x02 |
| * RemoveAllScenes                                                   |   0x03 |
| * StoreScene                                                        |   0x04 |
| * RecallScene                                                       |   0x05 |
| * GetSceneMembership                                                |   0x06 |
| * EnhancedAddScene                                                  |   0x40 |
| * EnhancedViewScene                                                 |   0x41 |
| * CopyScene                                                         |   0x42 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * SceneCount                                                        | 0x0000 |
| * CurrentScene                                                      | 0x0001 |
| * CurrentGroup                                                      | 0x0002 |
| * SceneValid                                                        | 0x0003 |
| * NameSupport                                                       | 0x0004 |
| * LastConfiguredBy                                                  | 0x0005 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command AddScene
 */
class ScenesAddScene : public ClusterCommand {
public:
    ScenesAddScene()
        : ClusterCommand("add-scene")
        , mComplex_ExtensionFieldSets(&mRequest.extensionFieldSets)
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("SceneID", 0, UINT8_MAX, &mRequest.sceneID);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("SceneName", &mRequest.sceneName);
        AddArgument("ExtensionFieldSets", &mComplex_ExtensionFieldSets);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterAddSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.sceneID = [NSNumber numberWithUnsignedChar:mRequest.sceneID];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.sceneName = [[NSString alloc] initWithBytes:mRequest.sceneName.data()
                                                    length:mRequest.sceneName.size()
                                                  encoding:NSUTF8StringEncoding];
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.extensionFieldSets) {
                MTRScenesClusterExtensionFieldSet * newElement_0;
                newElement_0 = [MTRScenesClusterExtensionFieldSet new];
                newElement_0.clusterID = [NSNumber numberWithUnsignedInt:entry_0.clusterID];
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.attributeValueList) {
                        MTRScenesClusterAttributeValuePair * newElement_2;
                        newElement_2 = [MTRScenesClusterAttributeValuePair new];
                        if (entry_2.attributeID.HasValue()) {
                            newElement_2.attributeID = [NSNumber numberWithUnsignedInt:entry_2.attributeID.Value()];
                        } else {
                            newElement_2.attributeID = nil;
                        }
                        { // Scope for our temporary variables
                            auto * array_4 = [NSMutableArray new];
                            for (auto & entry_4 : entry_2.attributeValue) {
                                NSNumber * newElement_4;
                                newElement_4 = [NSNumber numberWithUnsignedChar:entry_4];
                                [array_4 addObject:newElement_4];
                            }
                            newElement_2.attributeValue = array_4;
                        }
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.attributeValueList = array_2;
                }
                [array_0 addObject:newElement_0];
            }
            params.extensionFieldSets = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster addSceneWithParams:params
                             completion:^(MTRScenesClusterAddSceneResponseParams * _Nullable values, NSError * _Nullable error) {
                                 NSLog(@"Values: %@", values);
                                 responsesNeeded--;
                                 if (error != nil) {
                                     mError = error;
                                     LogNSError("Error", error);
                                 }
                                 if (responsesNeeded == 0) {
                                     SetCommandExitStatus(mError);
                                 }
                             }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::AddScene::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::Scenes::Structs::ExtensionFieldSet::Type>>
        mComplex_ExtensionFieldSets;
};

/*
 * Command ViewScene
 */
class ScenesViewScene : public ClusterCommand {
public:
    ScenesViewScene()
        : ClusterCommand("view-scene")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("SceneID", 0, UINT8_MAX, &mRequest.sceneID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterViewSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.sceneID = [NSNumber numberWithUnsignedChar:mRequest.sceneID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster viewSceneWithParams:params
                              completion:^(MTRScenesClusterViewSceneResponseParams * _Nullable values, NSError * _Nullable error) {
                                  NSLog(@"Values: %@", values);
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::ViewScene::Type mRequest;
};

/*
 * Command RemoveScene
 */
class ScenesRemoveScene : public ClusterCommand {
public:
    ScenesRemoveScene()
        : ClusterCommand("remove-scene")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("SceneID", 0, UINT8_MAX, &mRequest.sceneID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterRemoveSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.sceneID = [NSNumber numberWithUnsignedChar:mRequest.sceneID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                removeSceneWithParams:params
                           completion:^(MTRScenesClusterRemoveSceneResponseParams * _Nullable values, NSError * _Nullable error) {
                               NSLog(@"Values: %@", values);
                               responsesNeeded--;
                               if (error != nil) {
                                   mError = error;
                                   LogNSError("Error", error);
                               }
                               if (responsesNeeded == 0) {
                                   SetCommandExitStatus(mError);
                               }
                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::RemoveScene::Type mRequest;
};

/*
 * Command RemoveAllScenes
 */
class ScenesRemoveAllScenes : public ClusterCommand {
public:
    ScenesRemoveAllScenes()
        : ClusterCommand("remove-all-scenes")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterRemoveAllScenesParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster removeAllScenesWithParams:params
                                    completion:^(MTRScenesClusterRemoveAllScenesResponseParams * _Nullable values,
                                        NSError * _Nullable error) {
                                        NSLog(@"Values: %@", values);
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::RemoveAllScenes::Type mRequest;
};

/*
 * Command StoreScene
 */
class ScenesStoreScene : public ClusterCommand {
public:
    ScenesStoreScene()
        : ClusterCommand("store-scene")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("SceneID", 0, UINT8_MAX, &mRequest.sceneID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterStoreSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.sceneID = [NSNumber numberWithUnsignedChar:mRequest.sceneID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                storeSceneWithParams:params
                          completion:^(MTRScenesClusterStoreSceneResponseParams * _Nullable values, NSError * _Nullable error) {
                              NSLog(@"Values: %@", values);
                              responsesNeeded--;
                              if (error != nil) {
                                  mError = error;
                                  LogNSError("Error", error);
                              }
                              if (responsesNeeded == 0) {
                                  SetCommandExitStatus(mError);
                              }
                          }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::StoreScene::Type mRequest;
};

/*
 * Command RecallScene
 */
class ScenesRecallScene : public ClusterCommand {
public:
    ScenesRecallScene()
        : ClusterCommand("recall-scene")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("SceneID", 0, UINT8_MAX, &mRequest.sceneID);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterRecallSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.sceneID = [NSNumber numberWithUnsignedChar:mRequest.sceneID];
        if (mRequest.transitionTime.HasValue()) {
            if (mRequest.transitionTime.Value().IsNull()) {
                params.transitionTime = nil;
            } else {
                params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime.Value().Value()];
            }
        } else {
            params.transitionTime = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster recallSceneWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::RecallScene::Type mRequest;
};

/*
 * Command GetSceneMembership
 */
class ScenesGetSceneMembership : public ClusterCommand {
public:
    ScenesGetSceneMembership()
        : ClusterCommand("get-scene-membership")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterGetSceneMembershipParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getSceneMembershipWithParams:params
                                       completion:^(MTRScenesClusterGetSceneMembershipResponseParams * _Nullable values,
                                           NSError * _Nullable error) {
                                           NSLog(@"Values: %@", values);
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::GetSceneMembership::Type mRequest;
};

/*
 * Command EnhancedAddScene
 */
class ScenesEnhancedAddScene : public ClusterCommand {
public:
    ScenesEnhancedAddScene()
        : ClusterCommand("enhanced-add-scene")
        , mComplex_ExtensionFieldSets(&mRequest.extensionFieldSets)
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("SceneID", 0, UINT8_MAX, &mRequest.sceneID);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("SceneName", &mRequest.sceneName);
        AddArgument("ExtensionFieldSets", &mComplex_ExtensionFieldSets);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000040) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterEnhancedAddSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.sceneID = [NSNumber numberWithUnsignedChar:mRequest.sceneID];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.sceneName = [[NSString alloc] initWithBytes:mRequest.sceneName.data()
                                                    length:mRequest.sceneName.size()
                                                  encoding:NSUTF8StringEncoding];
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.extensionFieldSets) {
                MTRScenesClusterExtensionFieldSet * newElement_0;
                newElement_0 = [MTRScenesClusterExtensionFieldSet new];
                newElement_0.clusterID = [NSNumber numberWithUnsignedInt:entry_0.clusterID];
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.attributeValueList) {
                        MTRScenesClusterAttributeValuePair * newElement_2;
                        newElement_2 = [MTRScenesClusterAttributeValuePair new];
                        if (entry_2.attributeID.HasValue()) {
                            newElement_2.attributeID = [NSNumber numberWithUnsignedInt:entry_2.attributeID.Value()];
                        } else {
                            newElement_2.attributeID = nil;
                        }
                        { // Scope for our temporary variables
                            auto * array_4 = [NSMutableArray new];
                            for (auto & entry_4 : entry_2.attributeValue) {
                                NSNumber * newElement_4;
                                newElement_4 = [NSNumber numberWithUnsignedChar:entry_4];
                                [array_4 addObject:newElement_4];
                            }
                            newElement_2.attributeValue = array_4;
                        }
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.attributeValueList = array_2;
                }
                [array_0 addObject:newElement_0];
            }
            params.extensionFieldSets = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enhancedAddSceneWithParams:params
                                     completion:^(MTRScenesClusterEnhancedAddSceneResponseParams * _Nullable values,
                                         NSError * _Nullable error) {
                                         NSLog(@"Values: %@", values);
                                         responsesNeeded--;
                                         if (error != nil) {
                                             mError = error;
                                             LogNSError("Error", error);
                                         }
                                         if (responsesNeeded == 0) {
                                             SetCommandExitStatus(mError);
                                         }
                                     }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::EnhancedAddScene::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::Scenes::Structs::ExtensionFieldSet::Type>>
        mComplex_ExtensionFieldSets;
};

/*
 * Command EnhancedViewScene
 */
class ScenesEnhancedViewScene : public ClusterCommand {
public:
    ScenesEnhancedViewScene()
        : ClusterCommand("enhanced-view-scene")
    {
        AddArgument("GroupID", 0, UINT16_MAX, &mRequest.groupID);
        AddArgument("SceneID", 0, UINT8_MAX, &mRequest.sceneID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000041) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterEnhancedViewSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupID = [NSNumber numberWithUnsignedShort:mRequest.groupID];
        params.sceneID = [NSNumber numberWithUnsignedChar:mRequest.sceneID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enhancedViewSceneWithParams:params
                                      completion:^(MTRScenesClusterEnhancedViewSceneResponseParams * _Nullable values,
                                          NSError * _Nullable error) {
                                          NSLog(@"Values: %@", values);
                                          responsesNeeded--;
                                          if (error != nil) {
                                              mError = error;
                                              LogNSError("Error", error);
                                          }
                                          if (responsesNeeded == 0) {
                                              SetCommandExitStatus(mError);
                                          }
                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::EnhancedViewScene::Type mRequest;
};

/*
 * Command CopyScene
 */
class ScenesCopyScene : public ClusterCommand {
public:
    ScenesCopyScene()
        : ClusterCommand("copy-scene")
    {
        AddArgument("Mode", 0, UINT8_MAX, &mRequest.mode);
        AddArgument("GroupIdentifierFrom", 0, UINT16_MAX, &mRequest.groupIdentifierFrom);
        AddArgument("SceneIdentifierFrom", 0, UINT8_MAX, &mRequest.sceneIdentifierFrom);
        AddArgument("GroupIdentifierTo", 0, UINT16_MAX, &mRequest.groupIdentifierTo);
        AddArgument("SceneIdentifierTo", 0, UINT8_MAX, &mRequest.sceneIdentifierTo);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) command (0x00000042) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRScenesClusterCopySceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.mode = [NSNumber numberWithUnsignedChar:mRequest.mode.Raw()];
        params.groupIdentifierFrom = [NSNumber numberWithUnsignedShort:mRequest.groupIdentifierFrom];
        params.sceneIdentifierFrom = [NSNumber numberWithUnsignedChar:mRequest.sceneIdentifierFrom];
        params.groupIdentifierTo = [NSNumber numberWithUnsignedShort:mRequest.groupIdentifierTo];
        params.sceneIdentifierTo = [NSNumber numberWithUnsignedChar:mRequest.sceneIdentifierTo];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster copySceneWithParams:params
                              completion:^(MTRScenesClusterCopySceneResponseParams * _Nullable values, NSError * _Nullable error) {
                                  NSLog(@"Values: %@", values);
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Scenes::Commands::CopyScene::Type mRequest;
};

/*
 * Attribute SceneCount
 */
class ReadScenesSceneCount : public ReadAttribute {
public:
    ReadScenesSceneCount()
        : ReadAttribute("scene-count")
    {
    }

    ~ReadScenesSceneCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeSceneCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.SceneCount response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes SceneCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesSceneCount : public SubscribeAttribute {
public:
    SubscribeAttributeScenesSceneCount()
        : SubscribeAttribute("scene-count")
    {
    }

    ~SubscribeAttributeScenesSceneCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSceneCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.SceneCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentScene
 */
class ReadScenesCurrentScene : public ReadAttribute {
public:
    ReadScenesCurrentScene()
        : ReadAttribute("current-scene")
    {
    }

    ~ReadScenesCurrentScene() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeCurrentSceneWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.CurrentScene response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes CurrentScene read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesCurrentScene : public SubscribeAttribute {
public:
    SubscribeAttributeScenesCurrentScene()
        : SubscribeAttribute("current-scene")
    {
    }

    ~SubscribeAttributeScenesCurrentScene() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentSceneWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.CurrentScene response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentGroup
 */
class ReadScenesCurrentGroup : public ReadAttribute {
public:
    ReadScenesCurrentGroup()
        : ReadAttribute("current-group")
    {
    }

    ~ReadScenesCurrentGroup() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeCurrentGroupWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.CurrentGroup response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes CurrentGroup read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesCurrentGroup : public SubscribeAttribute {
public:
    SubscribeAttributeScenesCurrentGroup()
        : SubscribeAttribute("current-group")
    {
    }

    ~SubscribeAttributeScenesCurrentGroup() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentGroupWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.CurrentGroup response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SceneValid
 */
class ReadScenesSceneValid : public ReadAttribute {
public:
    ReadScenesSceneValid()
        : ReadAttribute("scene-valid")
    {
    }

    ~ReadScenesSceneValid() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeSceneValidWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.SceneValid response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes SceneValid read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesSceneValid : public SubscribeAttribute {
public:
    SubscribeAttributeScenesSceneValid()
        : SubscribeAttribute("scene-valid")
    {
    }

    ~SubscribeAttributeScenesSceneValid() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSceneValidWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.SceneValid response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NameSupport
 */
class ReadScenesNameSupport : public ReadAttribute {
public:
    ReadScenesNameSupport()
        : ReadAttribute("name-support")
    {
    }

    ~ReadScenesNameSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNameSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.NameSupport response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes NameSupport read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesNameSupport : public SubscribeAttribute {
public:
    SubscribeAttributeScenesNameSupport()
        : SubscribeAttribute("name-support")
    {
    }

    ~SubscribeAttributeScenesNameSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNameSupportWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.NameSupport response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LastConfiguredBy
 */
class ReadScenesLastConfiguredBy : public ReadAttribute {
public:
    ReadScenesLastConfiguredBy()
        : ReadAttribute("last-configured-by")
    {
    }

    ~ReadScenesLastConfiguredBy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeLastConfiguredByWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.LastConfiguredBy response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes LastConfiguredBy read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesLastConfiguredBy : public SubscribeAttribute {
public:
    SubscribeAttributeScenesLastConfiguredBy()
        : SubscribeAttribute("last-configured-by")
    {
    }

    ~SubscribeAttributeScenesLastConfiguredBy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLastConfiguredByWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.LastConfiguredBy response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadScenesGeneratedCommandList : public ReadAttribute {
public:
    ReadScenesGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadScenesGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeScenesGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeScenesGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadScenesAcceptedCommandList : public ReadAttribute {
public:
    ReadScenesAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadScenesAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeScenesAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeScenesAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadScenesAttributeList : public ReadAttribute {
public:
    ReadScenesAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadScenesAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeScenesAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeScenesAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadScenesFeatureMap : public ReadAttribute {
public:
    ReadScenesFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadScenesFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeScenesFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeScenesFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadScenesClusterRevision : public ReadAttribute {
public:
    ReadScenesClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadScenesClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeScenesClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeScenesClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterScenes alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster OnOff                                                       | 0x0006 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * Off                                                               |   0x00 |
| * On                                                                |   0x01 |
| * Toggle                                                            |   0x02 |
| * OffWithEffect                                                     |   0x40 |
| * OnWithRecallGlobalScene                                           |   0x41 |
| * OnWithTimedOff                                                    |   0x42 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * OnOff                                                             | 0x0000 |
| * GlobalSceneControl                                                | 0x4000 |
| * OnTime                                                            | 0x4001 |
| * OffWaitTime                                                       | 0x4002 |
| * StartUpOnOff                                                      | 0x4003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command Off
 */
class OnOffOff : public ClusterCommand {
public:
    OnOffOff()
        : ClusterCommand("off")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTROnOffClusterOffParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster offWithParams:params
                        completion:^(NSError * _Nullable error) {
                            responsesNeeded--;
                            if (error != nil) {
                                mError = error;
                                LogNSError("Error", error);
                            }
                            if (responsesNeeded == 0) {
                                SetCommandExitStatus(mError);
                            }
                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command On
 */
class OnOffOn : public ClusterCommand {
public:
    OnOffOn()
        : ClusterCommand("on")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTROnOffClusterOnParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster onWithParams:params
                       completion:^(NSError * _Nullable error) {
                           responsesNeeded--;
                           if (error != nil) {
                               mError = error;
                               LogNSError("Error", error);
                           }
                           if (responsesNeeded == 0) {
                               SetCommandExitStatus(mError);
                           }
                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command Toggle
 */
class OnOffToggle : public ClusterCommand {
public:
    OnOffToggle()
        : ClusterCommand("toggle")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTROnOffClusterToggleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster toggleWithParams:params
                           completion:^(NSError * _Nullable error) {
                               responsesNeeded--;
                               if (error != nil) {
                                   mError = error;
                                   LogNSError("Error", error);
                               }
                               if (responsesNeeded == 0) {
                                   SetCommandExitStatus(mError);
                               }
                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command OffWithEffect
 */
class OnOffOffWithEffect : public ClusterCommand {
public:
    OnOffOffWithEffect()
        : ClusterCommand("off-with-effect")
    {
        AddArgument("EffectIdentifier", 0, UINT8_MAX, &mRequest.effectIdentifier);
        AddArgument("EffectVariant", 0, UINT8_MAX, &mRequest.effectVariant);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) command (0x00000040) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTROnOffClusterOffWithEffectParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.effectIdentifier = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.effectIdentifier)];
        params.effectVariant = [NSNumber numberWithUnsignedChar:mRequest.effectVariant];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster offWithEffectWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OnOff::Commands::OffWithEffect::Type mRequest;
};

/*
 * Command OnWithRecallGlobalScene
 */
class OnOffOnWithRecallGlobalScene : public ClusterCommand {
public:
    OnOffOnWithRecallGlobalScene()
        : ClusterCommand("on-with-recall-global-scene")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) command (0x00000041) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTROnOffClusterOnWithRecallGlobalSceneParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster onWithRecallGlobalSceneWithParams:params
                                            completion:^(NSError * _Nullable error) {
                                                responsesNeeded--;
                                                if (error != nil) {
                                                    mError = error;
                                                    LogNSError("Error", error);
                                                }
                                                if (responsesNeeded == 0) {
                                                    SetCommandExitStatus(mError);
                                                }
                                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command OnWithTimedOff
 */
class OnOffOnWithTimedOff : public ClusterCommand {
public:
    OnOffOnWithTimedOff()
        : ClusterCommand("on-with-timed-off")
    {
        AddArgument("OnOffControl", 0, UINT8_MAX, &mRequest.onOffControl);
        AddArgument("OnTime", 0, UINT16_MAX, &mRequest.onTime);
        AddArgument("OffWaitTime", 0, UINT16_MAX, &mRequest.offWaitTime);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) command (0x00000042) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTROnOffClusterOnWithTimedOffParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.onOffControl = [NSNumber numberWithUnsignedChar:mRequest.onOffControl.Raw()];
        params.onTime = [NSNumber numberWithUnsignedShort:mRequest.onTime];
        params.offWaitTime = [NSNumber numberWithUnsignedShort:mRequest.offWaitTime];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster onWithTimedOffWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OnOff::Commands::OnWithTimedOff::Type mRequest;
};

/*
 * Attribute OnOff
 */
class ReadOnOffOnOff : public ReadAttribute {
public:
    ReadOnOffOnOff()
        : ReadAttribute("on-off")
    {
    }

    ~ReadOnOffOnOff() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeOnOffWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.OnOff response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff OnOff read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffOnOff : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffOnOff()
        : SubscribeAttribute("on-off")
    {
    }

    ~SubscribeAttributeOnOffOnOff() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOnOffWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.OnOff response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GlobalSceneControl
 */
class ReadOnOffGlobalSceneControl : public ReadAttribute {
public:
    ReadOnOffGlobalSceneControl()
        : ReadAttribute("global-scene-control")
    {
    }

    ~ReadOnOffGlobalSceneControl() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x00004000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGlobalSceneControlWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.GlobalSceneControl response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff GlobalSceneControl read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffGlobalSceneControl : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffGlobalSceneControl()
        : SubscribeAttribute("global-scene-control")
    {
    }

    ~SubscribeAttributeOnOffGlobalSceneControl() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x00004000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGlobalSceneControlWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.GlobalSceneControl response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OnTime
 */
class ReadOnOffOnTime : public ReadAttribute {
public:
    ReadOnOffOnTime()
        : ReadAttribute("on-time")
    {
    }

    ~ReadOnOffOnTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x00004001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeOnTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.OnTime response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff OnTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOnOffOnTime : public WriteAttribute {
public:
    WriteOnOffOnTime()
        : WriteAttribute("on-time")
    {
        AddArgument("attr-name", "on-time");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOnOffOnTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) WriteAttribute (0x00004001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeOnTimeWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("OnOff OnTime write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOnOffOnTime : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffOnTime()
        : SubscribeAttribute("on-time")
    {
    }

    ~SubscribeAttributeOnOffOnTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x00004001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOnTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.OnTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OffWaitTime
 */
class ReadOnOffOffWaitTime : public ReadAttribute {
public:
    ReadOnOffOffWaitTime()
        : ReadAttribute("off-wait-time")
    {
    }

    ~ReadOnOffOffWaitTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x00004002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeOffWaitTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.OffWaitTime response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff OffWaitTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOnOffOffWaitTime : public WriteAttribute {
public:
    WriteOnOffOffWaitTime()
        : WriteAttribute("off-wait-time")
    {
        AddArgument("attr-name", "off-wait-time");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOnOffOffWaitTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) WriteAttribute (0x00004002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeOffWaitTimeWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("OnOff OffWaitTime write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOnOffOffWaitTime : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffOffWaitTime()
        : SubscribeAttribute("off-wait-time")
    {
    }

    ~SubscribeAttributeOnOffOffWaitTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x00004002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOffWaitTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.OffWaitTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StartUpOnOff
 */
class ReadOnOffStartUpOnOff : public ReadAttribute {
public:
    ReadOnOffStartUpOnOff()
        : ReadAttribute("start-up-on-off")
    {
    }

    ~ReadOnOffStartUpOnOff() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x00004003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeStartUpOnOffWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.StartUpOnOff response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff StartUpOnOff read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOnOffStartUpOnOff : public WriteAttribute {
public:
    WriteOnOffStartUpOnOff()
        : WriteAttribute("start-up-on-off")
    {
        AddArgument("attr-name", "start-up-on-off");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOnOffStartUpOnOff() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) WriteAttribute (0x00004003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeStartUpOnOffWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("OnOff StartUpOnOff write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeOnOffStartUpOnOff : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffStartUpOnOff()
        : SubscribeAttribute("start-up-on-off")
    {
    }

    ~SubscribeAttributeOnOffStartUpOnOff() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x00004003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStartUpOnOffWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.StartUpOnOff response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadOnOffGeneratedCommandList : public ReadAttribute {
public:
    ReadOnOffGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadOnOffGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeOnOffGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadOnOffAcceptedCommandList : public ReadAttribute {
public:
    ReadOnOffAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadOnOffAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeOnOffAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadOnOffAttributeList : public ReadAttribute {
public:
    ReadOnOffAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadOnOffAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeOnOffAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadOnOffFeatureMap : public ReadAttribute {
public:
    ReadOnOffFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadOnOffFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeOnOffFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadOnOffClusterRevision : public ReadAttribute {
public:
    ReadOnOffClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadOnOffClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeOnOffClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster OnOffSwitchConfiguration                                    | 0x0007 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * SwitchType                                                        | 0x0000 |
| * SwitchActions                                                     | 0x0010 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute SwitchType
 */
class ReadOnOffSwitchConfigurationSwitchType : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationSwitchType()
        : ReadAttribute("switch-type")
    {
    }

    ~ReadOnOffSwitchConfigurationSwitchType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeSwitchTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.SwitchType response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration SwitchType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffSwitchConfigurationSwitchType : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationSwitchType()
        : SubscribeAttribute("switch-type")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationSwitchType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSwitchTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.SwitchType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SwitchActions
 */
class ReadOnOffSwitchConfigurationSwitchActions : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationSwitchActions()
        : ReadAttribute("switch-actions")
    {
    }

    ~ReadOnOffSwitchConfigurationSwitchActions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeSwitchActionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.SwitchActions response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration SwitchActions read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOnOffSwitchConfigurationSwitchActions : public WriteAttribute {
public:
    WriteOnOffSwitchConfigurationSwitchActions()
        : WriteAttribute("switch-actions")
    {
        AddArgument("attr-name", "switch-actions");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOnOffSwitchConfigurationSwitchActions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) WriteAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeSwitchActionsWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("OnOffSwitchConfiguration SwitchActions write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeOnOffSwitchConfigurationSwitchActions : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationSwitchActions()
        : SubscribeAttribute("switch-actions")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationSwitchActions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSwitchActionsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.SwitchActions response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadOnOffSwitchConfigurationGeneratedCommandList : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadOnOffSwitchConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffSwitchConfigurationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadOnOffSwitchConfigurationAcceptedCommandList : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadOnOffSwitchConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffSwitchConfigurationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadOnOffSwitchConfigurationAttributeList : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadOnOffSwitchConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffSwitchConfigurationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadOnOffSwitchConfigurationFeatureMap : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadOnOffSwitchConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffSwitchConfigurationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadOnOffSwitchConfigurationClusterRevision : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadOnOffSwitchConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffSwitchConfigurationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOnOffSwitchConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster LevelControl                                                | 0x0008 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * MoveToLevel                                                       |   0x00 |
| * Move                                                              |   0x01 |
| * Step                                                              |   0x02 |
| * Stop                                                              |   0x03 |
| * MoveToLevelWithOnOff                                              |   0x04 |
| * MoveWithOnOff                                                     |   0x05 |
| * StepWithOnOff                                                     |   0x06 |
| * StopWithOnOff                                                     |   0x07 |
| * MoveToClosestFrequency                                            |   0x08 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * CurrentLevel                                                      | 0x0000 |
| * RemainingTime                                                     | 0x0001 |
| * MinLevel                                                          | 0x0002 |
| * MaxLevel                                                          | 0x0003 |
| * CurrentFrequency                                                  | 0x0004 |
| * MinFrequency                                                      | 0x0005 |
| * MaxFrequency                                                      | 0x0006 |
| * Options                                                           | 0x000F |
| * OnOffTransitionTime                                               | 0x0010 |
| * OnLevel                                                           | 0x0011 |
| * OnTransitionTime                                                  | 0x0012 |
| * OffTransitionTime                                                 | 0x0013 |
| * DefaultMoveRate                                                   | 0x0014 |
| * StartUpCurrentLevel                                               | 0x4000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command MoveToLevel
 */
class LevelControlMoveToLevel : public ClusterCommand {
public:
    LevelControlMoveToLevel()
        : ClusterCommand("move-to-level")
    {
        AddArgument("Level", 0, UINT8_MAX, &mRequest.level);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterMoveToLevelParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.level = [NSNumber numberWithUnsignedChar:mRequest.level];
        if (mRequest.transitionTime.IsNull()) {
            params.transitionTime = nil;
        } else {
            params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime.Value()];
        }
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToLevelWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::MoveToLevel::Type mRequest;
};

/*
 * Command Move
 */
class LevelControlMove : public ClusterCommand {
public:
    LevelControlMove()
        : ClusterCommand("move")
    {
        AddArgument("MoveMode", 0, UINT8_MAX, &mRequest.moveMode);
        AddArgument("Rate", 0, UINT8_MAX, &mRequest.rate);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterMoveParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.moveMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.moveMode)];
        if (mRequest.rate.IsNull()) {
            params.rate = nil;
        } else {
            params.rate = [NSNumber numberWithUnsignedChar:mRequest.rate.Value()];
        }
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveWithParams:params
                         completion:^(NSError * _Nullable error) {
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::Move::Type mRequest;
};

/*
 * Command Step
 */
class LevelControlStep : public ClusterCommand {
public:
    LevelControlStep()
        : ClusterCommand("step")
    {
        AddArgument("StepMode", 0, UINT8_MAX, &mRequest.stepMode);
        AddArgument("StepSize", 0, UINT8_MAX, &mRequest.stepSize);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterStepParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.stepMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.stepMode)];
        params.stepSize = [NSNumber numberWithUnsignedChar:mRequest.stepSize];
        if (mRequest.transitionTime.IsNull()) {
            params.transitionTime = nil;
        } else {
            params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime.Value()];
        }
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stepWithParams:params
                         completion:^(NSError * _Nullable error) {
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::Step::Type mRequest;
};

/*
 * Command Stop
 */
class LevelControlStop : public ClusterCommand {
public:
    LevelControlStop()
        : ClusterCommand("stop")
    {
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterStopParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stopWithParams:params
                         completion:^(NSError * _Nullable error) {
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::Stop::Type mRequest;
};

/*
 * Command MoveToLevelWithOnOff
 */
class LevelControlMoveToLevelWithOnOff : public ClusterCommand {
public:
    LevelControlMoveToLevelWithOnOff()
        : ClusterCommand("move-to-level-with-on-off")
    {
        AddArgument("Level", 0, UINT8_MAX, &mRequest.level);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterMoveToLevelWithOnOffParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.level = [NSNumber numberWithUnsignedChar:mRequest.level];
        if (mRequest.transitionTime.IsNull()) {
            params.transitionTime = nil;
        } else {
            params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime.Value()];
        }
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToLevelWithOnOffWithParams:params
                                         completion:^(NSError * _Nullable error) {
                                             responsesNeeded--;
                                             if (error != nil) {
                                                 mError = error;
                                                 LogNSError("Error", error);
                                             }
                                             if (responsesNeeded == 0) {
                                                 SetCommandExitStatus(mError);
                                             }
                                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::MoveToLevelWithOnOff::Type mRequest;
};

/*
 * Command MoveWithOnOff
 */
class LevelControlMoveWithOnOff : public ClusterCommand {
public:
    LevelControlMoveWithOnOff()
        : ClusterCommand("move-with-on-off")
    {
        AddArgument("MoveMode", 0, UINT8_MAX, &mRequest.moveMode);
        AddArgument("Rate", 0, UINT8_MAX, &mRequest.rate);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterMoveWithOnOffParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.moveMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.moveMode)];
        if (mRequest.rate.IsNull()) {
            params.rate = nil;
        } else {
            params.rate = [NSNumber numberWithUnsignedChar:mRequest.rate.Value()];
        }
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveWithOnOffWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::MoveWithOnOff::Type mRequest;
};

/*
 * Command StepWithOnOff
 */
class LevelControlStepWithOnOff : public ClusterCommand {
public:
    LevelControlStepWithOnOff()
        : ClusterCommand("step-with-on-off")
    {
        AddArgument("StepMode", 0, UINT8_MAX, &mRequest.stepMode);
        AddArgument("StepSize", 0, UINT8_MAX, &mRequest.stepSize);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterStepWithOnOffParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.stepMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.stepMode)];
        params.stepSize = [NSNumber numberWithUnsignedChar:mRequest.stepSize];
        if (mRequest.transitionTime.IsNull()) {
            params.transitionTime = nil;
        } else {
            params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime.Value()];
        }
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stepWithOnOffWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::StepWithOnOff::Type mRequest;
};

/*
 * Command StopWithOnOff
 */
class LevelControlStopWithOnOff : public ClusterCommand {
public:
    LevelControlStopWithOnOff()
        : ClusterCommand("stop-with-on-off")
    {
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterStopWithOnOffParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask.Raw()];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stopWithOnOffWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::StopWithOnOff::Type mRequest;
};

/*
 * Command MoveToClosestFrequency
 */
class LevelControlMoveToClosestFrequency : public ClusterCommand {
public:
    LevelControlMoveToClosestFrequency()
        : ClusterCommand("move-to-closest-frequency")
    {
        AddArgument("Frequency", 0, UINT16_MAX, &mRequest.frequency);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) command (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRLevelControlClusterMoveToClosestFrequencyParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.frequency = [NSNumber numberWithUnsignedShort:mRequest.frequency];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToClosestFrequencyWithParams:params
                                           completion:^(NSError * _Nullable error) {
                                               responsesNeeded--;
                                               if (error != nil) {
                                                   mError = error;
                                                   LogNSError("Error", error);
                                               }
                                               if (responsesNeeded == 0) {
                                                   SetCommandExitStatus(mError);
                                               }
                                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::LevelControl::Commands::MoveToClosestFrequency::Type mRequest;
};

/*
 * Attribute CurrentLevel
 */
class ReadLevelControlCurrentLevel : public ReadAttribute {
public:
    ReadLevelControlCurrentLevel()
        : ReadAttribute("current-level")
    {
    }

    ~ReadLevelControlCurrentLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeCurrentLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.CurrentLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl CurrentLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlCurrentLevel : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlCurrentLevel()
        : SubscribeAttribute("current-level")
    {
    }

    ~SubscribeAttributeLevelControlCurrentLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.CurrentLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RemainingTime
 */
class ReadLevelControlRemainingTime : public ReadAttribute {
public:
    ReadLevelControlRemainingTime()
        : ReadAttribute("remaining-time")
    {
    }

    ~ReadLevelControlRemainingTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeRemainingTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.RemainingTime response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl RemainingTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlRemainingTime : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlRemainingTime()
        : SubscribeAttribute("remaining-time")
    {
    }

    ~SubscribeAttributeLevelControlRemainingTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRemainingTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.RemainingTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinLevel
 */
class ReadLevelControlMinLevel : public ReadAttribute {
public:
    ReadLevelControlMinLevel()
        : ReadAttribute("min-level")
    {
    }

    ~ReadLevelControlMinLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeMinLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.MinLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl MinLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlMinLevel : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlMinLevel()
        : SubscribeAttribute("min-level")
    {
    }

    ~SubscribeAttributeLevelControlMinLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.MinLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxLevel
 */
class ReadLevelControlMaxLevel : public ReadAttribute {
public:
    ReadLevelControlMaxLevel()
        : ReadAttribute("max-level")
    {
    }

    ~ReadLevelControlMaxLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeMaxLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.MaxLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl MaxLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlMaxLevel : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlMaxLevel()
        : SubscribeAttribute("max-level")
    {
    }

    ~SubscribeAttributeLevelControlMaxLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.MaxLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentFrequency
 */
class ReadLevelControlCurrentFrequency : public ReadAttribute {
public:
    ReadLevelControlCurrentFrequency()
        : ReadAttribute("current-frequency")
    {
    }

    ~ReadLevelControlCurrentFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeCurrentFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.CurrentFrequency response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl CurrentFrequency read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlCurrentFrequency : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlCurrentFrequency()
        : SubscribeAttribute("current-frequency")
    {
    }

    ~SubscribeAttributeLevelControlCurrentFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentFrequencyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.CurrentFrequency response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinFrequency
 */
class ReadLevelControlMinFrequency : public ReadAttribute {
public:
    ReadLevelControlMinFrequency()
        : ReadAttribute("min-frequency")
    {
    }

    ~ReadLevelControlMinFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeMinFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.MinFrequency response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl MinFrequency read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlMinFrequency : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlMinFrequency()
        : SubscribeAttribute("min-frequency")
    {
    }

    ~SubscribeAttributeLevelControlMinFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinFrequencyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.MinFrequency response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxFrequency
 */
class ReadLevelControlMaxFrequency : public ReadAttribute {
public:
    ReadLevelControlMaxFrequency()
        : ReadAttribute("max-frequency")
    {
    }

    ~ReadLevelControlMaxFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeMaxFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.MaxFrequency response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl MaxFrequency read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlMaxFrequency : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlMaxFrequency()
        : SubscribeAttribute("max-frequency")
    {
    }

    ~SubscribeAttributeLevelControlMaxFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxFrequencyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.MaxFrequency response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Options
 */
class ReadLevelControlOptions : public ReadAttribute {
public:
    ReadLevelControlOptions()
        : ReadAttribute("options")
    {
    }

    ~ReadLevelControlOptions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeOptionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.Options response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl Options read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLevelControlOptions : public WriteAttribute {
public:
    WriteLevelControlOptions()
        : WriteAttribute("options")
    {
        AddArgument("attr-name", "options");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLevelControlOptions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) WriteAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOptionsWithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("LevelControl Options write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeLevelControlOptions : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlOptions()
        : SubscribeAttribute("options")
    {
    }

    ~SubscribeAttributeLevelControlOptions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOptionsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.Options response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OnOffTransitionTime
 */
class ReadLevelControlOnOffTransitionTime : public ReadAttribute {
public:
    ReadLevelControlOnOffTransitionTime()
        : ReadAttribute("on-off-transition-time")
    {
    }

    ~ReadLevelControlOnOffTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeOnOffTransitionTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.OnOffTransitionTime response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl OnOffTransitionTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLevelControlOnOffTransitionTime : public WriteAttribute {
public:
    WriteLevelControlOnOffTransitionTime()
        : WriteAttribute("on-off-transition-time")
    {
        AddArgument("attr-name", "on-off-transition-time");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLevelControlOnOffTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) WriteAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeOnOffTransitionTimeWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("LevelControl OnOffTransitionTime write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeLevelControlOnOffTransitionTime : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlOnOffTransitionTime()
        : SubscribeAttribute("on-off-transition-time")
    {
    }

    ~SubscribeAttributeLevelControlOnOffTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOnOffTransitionTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.OnOffTransitionTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OnLevel
 */
class ReadLevelControlOnLevel : public ReadAttribute {
public:
    ReadLevelControlOnLevel()
        : ReadAttribute("on-level")
    {
    }

    ~ReadLevelControlOnLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeOnLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.OnLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl OnLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLevelControlOnLevel : public WriteAttribute {
public:
    WriteLevelControlOnLevel()
        : WriteAttribute("on-level")
    {
        AddArgument("attr-name", "on-level");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLevelControlOnLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) WriteAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOnLevelWithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("LevelControl OnLevel write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeLevelControlOnLevel : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlOnLevel()
        : SubscribeAttribute("on-level")
    {
    }

    ~SubscribeAttributeLevelControlOnLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOnLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.OnLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OnTransitionTime
 */
class ReadLevelControlOnTransitionTime : public ReadAttribute {
public:
    ReadLevelControlOnTransitionTime()
        : ReadAttribute("on-transition-time")
    {
    }

    ~ReadLevelControlOnTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeOnTransitionTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.OnTransitionTime response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl OnTransitionTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLevelControlOnTransitionTime : public WriteAttribute {
public:
    WriteLevelControlOnTransitionTime()
        : WriteAttribute("on-transition-time")
    {
        AddArgument("attr-name", "on-transition-time");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLevelControlOnTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) WriteAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeOnTransitionTimeWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("LevelControl OnTransitionTime write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeLevelControlOnTransitionTime : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlOnTransitionTime()
        : SubscribeAttribute("on-transition-time")
    {
    }

    ~SubscribeAttributeLevelControlOnTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOnTransitionTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.OnTransitionTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OffTransitionTime
 */
class ReadLevelControlOffTransitionTime : public ReadAttribute {
public:
    ReadLevelControlOffTransitionTime()
        : ReadAttribute("off-transition-time")
    {
    }

    ~ReadLevelControlOffTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeOffTransitionTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.OffTransitionTime response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl OffTransitionTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLevelControlOffTransitionTime : public WriteAttribute {
public:
    WriteLevelControlOffTransitionTime()
        : WriteAttribute("off-transition-time")
    {
        AddArgument("attr-name", "off-transition-time");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLevelControlOffTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) WriteAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeOffTransitionTimeWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("LevelControl OffTransitionTime write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeLevelControlOffTransitionTime : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlOffTransitionTime()
        : SubscribeAttribute("off-transition-time")
    {
    }

    ~SubscribeAttributeLevelControlOffTransitionTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOffTransitionTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.OffTransitionTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DefaultMoveRate
 */
class ReadLevelControlDefaultMoveRate : public ReadAttribute {
public:
    ReadLevelControlDefaultMoveRate()
        : ReadAttribute("default-move-rate")
    {
    }

    ~ReadLevelControlDefaultMoveRate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeDefaultMoveRateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.DefaultMoveRate response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl DefaultMoveRate read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLevelControlDefaultMoveRate : public WriteAttribute {
public:
    WriteLevelControlDefaultMoveRate()
        : WriteAttribute("default-move-rate")
    {
        AddArgument("attr-name", "default-move-rate");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLevelControlDefaultMoveRate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) WriteAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeDefaultMoveRateWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("LevelControl DefaultMoveRate write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeLevelControlDefaultMoveRate : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlDefaultMoveRate()
        : SubscribeAttribute("default-move-rate")
    {
    }

    ~SubscribeAttributeLevelControlDefaultMoveRate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDefaultMoveRateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.DefaultMoveRate response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StartUpCurrentLevel
 */
class ReadLevelControlStartUpCurrentLevel : public ReadAttribute {
public:
    ReadLevelControlStartUpCurrentLevel()
        : ReadAttribute("start-up-current-level")
    {
    }

    ~ReadLevelControlStartUpCurrentLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x00004000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeStartUpCurrentLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.StartUpCurrentLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl StartUpCurrentLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLevelControlStartUpCurrentLevel : public WriteAttribute {
public:
    WriteLevelControlStartUpCurrentLevel()
        : WriteAttribute("start-up-current-level")
    {
        AddArgument("attr-name", "start-up-current-level");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLevelControlStartUpCurrentLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) WriteAttribute (0x00004000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeStartUpCurrentLevelWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("LevelControl StartUpCurrentLevel write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeLevelControlStartUpCurrentLevel : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlStartUpCurrentLevel()
        : SubscribeAttribute("start-up-current-level")
    {
    }

    ~SubscribeAttributeLevelControlStartUpCurrentLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x00004000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStartUpCurrentLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.StartUpCurrentLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadLevelControlGeneratedCommandList : public ReadAttribute {
public:
    ReadLevelControlGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadLevelControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeLevelControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadLevelControlAcceptedCommandList : public ReadAttribute {
public:
    ReadLevelControlAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadLevelControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeLevelControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadLevelControlAttributeList : public ReadAttribute {
public:
    ReadLevelControlAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadLevelControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeLevelControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadLevelControlFeatureMap : public ReadAttribute {
public:
    ReadLevelControlFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadLevelControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeLevelControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadLevelControlClusterRevision : public ReadAttribute {
public:
    ReadLevelControlClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadLevelControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeLevelControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster BinaryInputBasic                                            | 0x000F |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * ActiveText                                                        | 0x0004 |
| * Description                                                       | 0x001C |
| * InactiveText                                                      | 0x002E |
| * OutOfService                                                      | 0x0051 |
| * Polarity                                                          | 0x0054 |
| * PresentValue                                                      | 0x0055 |
| * Reliability                                                       | 0x0067 |
| * StatusFlags                                                       | 0x006F |
| * ApplicationType                                                   | 0x0100 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute ActiveText
 */
class ReadBinaryInputBasicActiveText : public ReadAttribute {
public:
    ReadBinaryInputBasicActiveText()
        : ReadAttribute("active-text")
    {
    }

    ~ReadBinaryInputBasicActiveText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeActiveTextWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.ActiveText response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic ActiveText read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBinaryInputBasicActiveText : public WriteAttribute {
public:
    WriteBinaryInputBasicActiveText()
        : WriteAttribute("active-text")
    {
        AddArgument("attr-name", "active-text");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBinaryInputBasicActiveText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) WriteAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeActiveTextWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("BinaryInputBasic ActiveText write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBinaryInputBasicActiveText : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicActiveText()
        : SubscribeAttribute("active-text")
    {
    }

    ~SubscribeAttributeBinaryInputBasicActiveText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveTextWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.ActiveText response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Description
 */
class ReadBinaryInputBasicDescription : public ReadAttribute {
public:
    ReadBinaryInputBasicDescription()
        : ReadAttribute("description")
    {
    }

    ~ReadBinaryInputBasicDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000001C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.Description response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic Description read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBinaryInputBasicDescription : public WriteAttribute {
public:
    WriteBinaryInputBasicDescription()
        : WriteAttribute("description")
    {
        AddArgument("attr-name", "description");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBinaryInputBasicDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) WriteAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeDescriptionWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("BinaryInputBasic Description write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBinaryInputBasicDescription : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicDescription()
        : SubscribeAttribute("description")
    {
    }

    ~SubscribeAttributeBinaryInputBasicDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDescriptionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.Description response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InactiveText
 */
class ReadBinaryInputBasicInactiveText : public ReadAttribute {
public:
    ReadBinaryInputBasicInactiveText()
        : ReadAttribute("inactive-text")
    {
    }

    ~ReadBinaryInputBasicInactiveText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000002E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeInactiveTextWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.InactiveText response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic InactiveText read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBinaryInputBasicInactiveText : public WriteAttribute {
public:
    WriteBinaryInputBasicInactiveText()
        : WriteAttribute("inactive-text")
    {
        AddArgument("attr-name", "inactive-text");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBinaryInputBasicInactiveText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) WriteAttribute (0x0000002E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeInactiveTextWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("BinaryInputBasic InactiveText write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBinaryInputBasicInactiveText : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicInactiveText()
        : SubscribeAttribute("inactive-text")
    {
    }

    ~SubscribeAttributeBinaryInputBasicInactiveText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000002E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInactiveTextWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.InactiveText response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OutOfService
 */
class ReadBinaryInputBasicOutOfService : public ReadAttribute {
public:
    ReadBinaryInputBasicOutOfService()
        : ReadAttribute("out-of-service")
    {
    }

    ~ReadBinaryInputBasicOutOfService() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x00000051) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeOutOfServiceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.OutOfService response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic OutOfService read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBinaryInputBasicOutOfService : public WriteAttribute {
public:
    WriteBinaryInputBasicOutOfService()
        : WriteAttribute("out-of-service")
    {
        AddArgument("attr-name", "out-of-service");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBinaryInputBasicOutOfService() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) WriteAttribute (0x00000051) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeOutOfServiceWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("BinaryInputBasic OutOfService write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeBinaryInputBasicOutOfService : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicOutOfService()
        : SubscribeAttribute("out-of-service")
    {
    }

    ~SubscribeAttributeBinaryInputBasicOutOfService() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x00000051) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOutOfServiceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.OutOfService response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Polarity
 */
class ReadBinaryInputBasicPolarity : public ReadAttribute {
public:
    ReadBinaryInputBasicPolarity()
        : ReadAttribute("polarity")
    {
    }

    ~ReadBinaryInputBasicPolarity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x00000054) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePolarityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.Polarity response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic Polarity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicPolarity : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicPolarity()
        : SubscribeAttribute("polarity")
    {
    }

    ~SubscribeAttributeBinaryInputBasicPolarity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x00000054) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePolarityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.Polarity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PresentValue
 */
class ReadBinaryInputBasicPresentValue : public ReadAttribute {
public:
    ReadBinaryInputBasicPresentValue()
        : ReadAttribute("present-value")
    {
    }

    ~ReadBinaryInputBasicPresentValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x00000055) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePresentValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.PresentValue response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic PresentValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBinaryInputBasicPresentValue : public WriteAttribute {
public:
    WriteBinaryInputBasicPresentValue()
        : WriteAttribute("present-value")
    {
        AddArgument("attr-name", "present-value");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBinaryInputBasicPresentValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) WriteAttribute (0x00000055) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributePresentValueWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("BinaryInputBasic PresentValue write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeBinaryInputBasicPresentValue : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicPresentValue()
        : SubscribeAttribute("present-value")
    {
    }

    ~SubscribeAttributeBinaryInputBasicPresentValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x00000055) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePresentValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.PresentValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Reliability
 */
class ReadBinaryInputBasicReliability : public ReadAttribute {
public:
    ReadBinaryInputBasicReliability()
        : ReadAttribute("reliability")
    {
    }

    ~ReadBinaryInputBasicReliability() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x00000067) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeReliabilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.Reliability response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic Reliability read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBinaryInputBasicReliability : public WriteAttribute {
public:
    WriteBinaryInputBasicReliability()
        : WriteAttribute("reliability")
    {
        AddArgument("attr-name", "reliability");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBinaryInputBasicReliability() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) WriteAttribute (0x00000067) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeReliabilityWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("BinaryInputBasic Reliability write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeBinaryInputBasicReliability : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicReliability()
        : SubscribeAttribute("reliability")
    {
    }

    ~SubscribeAttributeBinaryInputBasicReliability() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x00000067) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReliabilityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.Reliability response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StatusFlags
 */
class ReadBinaryInputBasicStatusFlags : public ReadAttribute {
public:
    ReadBinaryInputBasicStatusFlags()
        : ReadAttribute("status-flags")
    {
    }

    ~ReadBinaryInputBasicStatusFlags() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000006F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeStatusFlagsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.StatusFlags response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic StatusFlags read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicStatusFlags : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicStatusFlags()
        : SubscribeAttribute("status-flags")
    {
    }

    ~SubscribeAttributeBinaryInputBasicStatusFlags() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000006F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStatusFlagsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.StatusFlags response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ApplicationType
 */
class ReadBinaryInputBasicApplicationType : public ReadAttribute {
public:
    ReadBinaryInputBasicApplicationType()
        : ReadAttribute("application-type")
    {
    }

    ~ReadBinaryInputBasicApplicationType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x00000100) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeApplicationTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.ApplicationType response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic ApplicationType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicApplicationType : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicApplicationType()
        : SubscribeAttribute("application-type")
    {
    }

    ~SubscribeAttributeBinaryInputBasicApplicationType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x00000100) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeApplicationTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.ApplicationType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadBinaryInputBasicGeneratedCommandList : public ReadAttribute {
public:
    ReadBinaryInputBasicGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadBinaryInputBasicGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeBinaryInputBasicGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadBinaryInputBasicAcceptedCommandList : public ReadAttribute {
public:
    ReadBinaryInputBasicAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadBinaryInputBasicAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeBinaryInputBasicAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadBinaryInputBasicAttributeList : public ReadAttribute {
public:
    ReadBinaryInputBasicAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadBinaryInputBasicAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeBinaryInputBasicAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadBinaryInputBasicFeatureMap : public ReadAttribute {
public:
    ReadBinaryInputBasicFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadBinaryInputBasicFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeBinaryInputBasicFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadBinaryInputBasicClusterRevision : public ReadAttribute {
public:
    ReadBinaryInputBasicClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadBinaryInputBasicClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeBinaryInputBasicClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinaryInputBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Descriptor                                                  | 0x001D |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * DeviceTypeList                                                    | 0x0000 |
| * ServerList                                                        | 0x0001 |
| * ClientList                                                        | 0x0002 |
| * PartsList                                                         | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute DeviceTypeList
 */
class ReadDescriptorDeviceTypeList : public ReadAttribute {
public:
    ReadDescriptorDeviceTypeList()
        : ReadAttribute("device-type-list")
    {
    }

    ~ReadDescriptorDeviceTypeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeDeviceTypeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.DeviceTypeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor DeviceTypeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorDeviceTypeList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorDeviceTypeList()
        : SubscribeAttribute("device-type-list")
    {
    }

    ~SubscribeAttributeDescriptorDeviceTypeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDeviceTypeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.DeviceTypeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ServerList
 */
class ReadDescriptorServerList : public ReadAttribute {
public:
    ReadDescriptorServerList()
        : ReadAttribute("server-list")
    {
    }

    ~ReadDescriptorServerList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeServerListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.ServerList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor ServerList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorServerList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorServerList()
        : SubscribeAttribute("server-list")
    {
    }

    ~SubscribeAttributeDescriptorServerList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeServerListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.ServerList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClientList
 */
class ReadDescriptorClientList : public ReadAttribute {
public:
    ReadDescriptorClientList()
        : ReadAttribute("client-list")
    {
    }

    ~ReadDescriptorClientList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeClientListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.ClientList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor ClientList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorClientList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorClientList()
        : SubscribeAttribute("client-list")
    {
    }

    ~SubscribeAttributeDescriptorClientList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClientListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.ClientList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PartsList
 */
class ReadDescriptorPartsList : public ReadAttribute {
public:
    ReadDescriptorPartsList()
        : ReadAttribute("parts-list")
    {
    }

    ~ReadDescriptorPartsList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributePartsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.PartsList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor PartsList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorPartsList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorPartsList()
        : SubscribeAttribute("parts-list")
    {
    }

    ~SubscribeAttributeDescriptorPartsList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePartsListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.PartsList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadDescriptorGeneratedCommandList : public ReadAttribute {
public:
    ReadDescriptorGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadDescriptorGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeDescriptorGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadDescriptorAcceptedCommandList : public ReadAttribute {
public:
    ReadDescriptorAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadDescriptorAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeDescriptorAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadDescriptorAttributeList : public ReadAttribute {
public:
    ReadDescriptorAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadDescriptorAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeDescriptorAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadDescriptorFeatureMap : public ReadAttribute {
public:
    ReadDescriptorFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadDescriptorFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeDescriptorFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadDescriptorClusterRevision : public ReadAttribute {
public:
    ReadDescriptorClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadDescriptorClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeDescriptorClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Binding                                                     | 0x001E |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Binding                                                           | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute Binding
 */
class ReadBindingBinding : public ReadAttribute {
public:
    ReadBindingBinding()
        : ReadAttribute("binding")
    {
    }

    ~ReadBindingBinding() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeBindingWithParams:params
                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                         NSLog(@"Binding.Binding response %@", [value description]);
                                         if (error != nil) {
                                             LogNSError("Binding Binding read Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }
};

class WriteBindingBinding : public WriteAttribute {
public:
    WriteBindingBinding()
        : WriteAttribute("binding")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "binding");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteBindingBinding() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRBindingClusterTargetStruct * newElement_0;
                newElement_0 = [MTRBindingClusterTargetStruct new];
                if (entry_0.node.HasValue()) {
                    newElement_0.node = [NSNumber numberWithUnsignedLongLong:entry_0.node.Value()];
                } else {
                    newElement_0.node = nil;
                }
                if (entry_0.group.HasValue()) {
                    newElement_0.group = [NSNumber numberWithUnsignedShort:entry_0.group.Value()];
                } else {
                    newElement_0.group = nil;
                }
                if (entry_0.endpoint.HasValue()) {
                    newElement_0.endpoint = [NSNumber numberWithUnsignedShort:entry_0.endpoint.Value()];
                } else {
                    newElement_0.endpoint = nil;
                }
                if (entry_0.cluster.HasValue()) {
                    newElement_0.cluster = [NSNumber numberWithUnsignedInt:entry_0.cluster.Value()];
                } else {
                    newElement_0.cluster = nil;
                }
                newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeBindingWithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("Binding Binding write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::Binding::Structs::TargetStruct::Type> mValue;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::Binding::Structs::TargetStruct::Type>> mComplex;
};

class SubscribeAttributeBindingBinding : public SubscribeAttribute {
public:
    SubscribeAttributeBindingBinding()
        : SubscribeAttribute("binding")
    {
    }

    ~SubscribeAttributeBindingBinding() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBindingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Binding.Binding response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadBindingGeneratedCommandList : public ReadAttribute {
public:
    ReadBindingGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadBindingGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Binding.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Binding GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBindingGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBindingGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeBindingGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Binding.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadBindingAcceptedCommandList : public ReadAttribute {
public:
    ReadBindingAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadBindingAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Binding.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Binding AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBindingAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBindingAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeBindingAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Binding.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadBindingAttributeList : public ReadAttribute {
public:
    ReadBindingAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadBindingAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Binding.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Binding AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBindingAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeBindingAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeBindingAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Binding.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadBindingFeatureMap : public ReadAttribute {
public:
    ReadBindingFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadBindingFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Binding.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Binding FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBindingFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeBindingFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeBindingFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Binding.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadBindingClusterRevision : public ReadAttribute {
public:
    ReadBindingClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadBindingClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Binding.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Binding ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBindingClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeBindingClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Binding.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster AccessControl                                               | 0x001F |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Acl                                                               | 0x0000 |
| * Extension                                                         | 0x0001 |
| * SubjectsPerAccessControlEntry                                     | 0x0002 |
| * TargetsPerAccessControlEntry                                      | 0x0003 |
| * AccessControlEntriesPerFabric                                     | 0x0004 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * AccessControlEntryChanged                                         | 0x0000 |
| * AccessControlExtensionChanged                                     | 0x0001 |
\*----------------------------------------------------------------------------*/

/*
 * Attribute Acl
 */
class ReadAccessControlAcl : public ReadAttribute {
public:
    ReadAccessControlAcl()
        : ReadAttribute("acl")
    {
    }

    ~ReadAccessControlAcl() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeACLWithParams:params
                                 completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                     NSLog(@"AccessControl.ACL response %@", [value description]);
                                     if (error != nil) {
                                         LogNSError("AccessControl ACL read Error", error);
                                     }
                                     SetCommandExitStatus(error);
                                 }];
        return CHIP_NO_ERROR;
    }
};

class WriteAccessControlAcl : public WriteAttribute {
public:
    WriteAccessControlAcl()
        : WriteAttribute("acl")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "acl");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteAccessControlAcl() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRAccessControlClusterAccessControlEntryStruct * newElement_0;
                newElement_0 = [MTRAccessControlClusterAccessControlEntryStruct new];
                newElement_0.privilege = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.privilege)];
                newElement_0.authMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.authMode)];
                if (entry_0.subjects.IsNull()) {
                    newElement_0.subjects = nil;
                } else {
                    { // Scope for our temporary variables
                        auto * array_3 = [NSMutableArray new];
                        for (auto & entry_3 : entry_0.subjects.Value()) {
                            NSNumber * newElement_3;
                            newElement_3 = [NSNumber numberWithUnsignedLongLong:entry_3];
                            [array_3 addObject:newElement_3];
                        }
                        newElement_0.subjects = array_3;
                    }
                }
                if (entry_0.targets.IsNull()) {
                    newElement_0.targets = nil;
                } else {
                    { // Scope for our temporary variables
                        auto * array_3 = [NSMutableArray new];
                        for (auto & entry_3 : entry_0.targets.Value()) {
                            MTRAccessControlClusterTarget * newElement_3;
                            newElement_3 = [MTRAccessControlClusterTarget new];
                            if (entry_3.cluster.IsNull()) {
                                newElement_3.cluster = nil;
                            } else {
                                newElement_3.cluster = [NSNumber numberWithUnsignedInt:entry_3.cluster.Value()];
                            }
                            if (entry_3.endpoint.IsNull()) {
                                newElement_3.endpoint = nil;
                            } else {
                                newElement_3.endpoint = [NSNumber numberWithUnsignedShort:entry_3.endpoint.Value()];
                            }
                            if (entry_3.deviceType.IsNull()) {
                                newElement_3.deviceType = nil;
                            } else {
                                newElement_3.deviceType = [NSNumber numberWithUnsignedInt:entry_3.deviceType.Value()];
                            }
                            [array_3 addObject:newElement_3];
                        }
                        newElement_0.targets = array_3;
                    }
                }
                newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeACLWithValue:value
                                     params:params
                                 completion:^(NSError * _Nullable error) {
                                     if (error != nil) {
                                         LogNSError("AccessControl ACL write Error", error);
                                     }
                                     SetCommandExitStatus(error);
                                 }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::AccessControl::Structs::AccessControlEntryStruct::Type> mValue;
    TypedComplexArgument<
        chip::app::DataModel::List<const chip::app::Clusters::AccessControl::Structs::AccessControlEntryStruct::Type>>
        mComplex;
};

class SubscribeAttributeAccessControlAcl : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlAcl()
        : SubscribeAttribute("acl")
    {
    }

    ~SubscribeAttributeAccessControlAcl() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACLWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.ACL response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Extension
 */
class ReadAccessControlExtension : public ReadAttribute {
public:
    ReadAccessControlExtension()
        : ReadAttribute("extension")
    {
    }

    ~ReadAccessControlExtension() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeExtensionWithParams:params
                                       completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                           NSLog(@"AccessControl.Extension response %@", [value description]);
                                           if (error != nil) {
                                               LogNSError("AccessControl Extension read Error", error);
                                           }
                                           SetCommandExitStatus(error);
                                       }];
        return CHIP_NO_ERROR;
    }
};

class WriteAccessControlExtension : public WriteAttribute {
public:
    WriteAccessControlExtension()
        : WriteAttribute("extension")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "extension");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteAccessControlExtension() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) WriteAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRAccessControlClusterAccessControlExtensionStruct * newElement_0;
                newElement_0 = [MTRAccessControlClusterAccessControlExtensionStruct new];
                newElement_0.data = [NSData dataWithBytes:entry_0.data.data() length:entry_0.data.size()];
                newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeExtensionWithValue:value
                                           params:params
                                       completion:^(NSError * _Nullable error) {
                                           if (error != nil) {
                                               LogNSError("AccessControl Extension write Error", error);
                                           }
                                           SetCommandExitStatus(error);
                                       }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::AccessControl::Structs::AccessControlExtensionStruct::Type> mValue;
    TypedComplexArgument<
        chip::app::DataModel::List<const chip::app::Clusters::AccessControl::Structs::AccessControlExtensionStruct::Type>>
        mComplex;
};

class SubscribeAttributeAccessControlExtension : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlExtension()
        : SubscribeAttribute("extension")
    {
    }

    ~SubscribeAttributeAccessControlExtension() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeExtensionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.Extension response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SubjectsPerAccessControlEntry
 */
class ReadAccessControlSubjectsPerAccessControlEntry : public ReadAttribute {
public:
    ReadAccessControlSubjectsPerAccessControlEntry()
        : ReadAttribute("subjects-per-access-control-entry")
    {
    }

    ~ReadAccessControlSubjectsPerAccessControlEntry() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeSubjectsPerAccessControlEntryWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.SubjectsPerAccessControlEntry response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl SubjectsPerAccessControlEntry read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlSubjectsPerAccessControlEntry : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlSubjectsPerAccessControlEntry()
        : SubscribeAttribute("subjects-per-access-control-entry")
    {
    }

    ~SubscribeAttributeAccessControlSubjectsPerAccessControlEntry() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSubjectsPerAccessControlEntryWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.SubjectsPerAccessControlEntry response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TargetsPerAccessControlEntry
 */
class ReadAccessControlTargetsPerAccessControlEntry : public ReadAttribute {
public:
    ReadAccessControlTargetsPerAccessControlEntry()
        : ReadAttribute("targets-per-access-control-entry")
    {
    }

    ~ReadAccessControlTargetsPerAccessControlEntry() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeTargetsPerAccessControlEntryWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.TargetsPerAccessControlEntry response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl TargetsPerAccessControlEntry read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlTargetsPerAccessControlEntry : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlTargetsPerAccessControlEntry()
        : SubscribeAttribute("targets-per-access-control-entry")
    {
    }

    ~SubscribeAttributeAccessControlTargetsPerAccessControlEntry() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTargetsPerAccessControlEntryWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.TargetsPerAccessControlEntry response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AccessControlEntriesPerFabric
 */
class ReadAccessControlAccessControlEntriesPerFabric : public ReadAttribute {
public:
    ReadAccessControlAccessControlEntriesPerFabric()
        : ReadAttribute("access-control-entries-per-fabric")
    {
    }

    ~ReadAccessControlAccessControlEntriesPerFabric() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeAccessControlEntriesPerFabricWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.AccessControlEntriesPerFabric response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl AccessControlEntriesPerFabric read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlAccessControlEntriesPerFabric : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlAccessControlEntriesPerFabric()
        : SubscribeAttribute("access-control-entries-per-fabric")
    {
    }

    ~SubscribeAttributeAccessControlAccessControlEntriesPerFabric() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAccessControlEntriesPerFabricWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.AccessControlEntriesPerFabric response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadAccessControlGeneratedCommandList : public ReadAttribute {
public:
    ReadAccessControlGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadAccessControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeAccessControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadAccessControlAcceptedCommandList : public ReadAttribute {
public:
    ReadAccessControlAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadAccessControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeAccessControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadAccessControlAttributeList : public ReadAttribute {
public:
    ReadAccessControlAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadAccessControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeAccessControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadAccessControlFeatureMap : public ReadAttribute {
public:
    ReadAccessControlFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadAccessControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeAccessControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadAccessControlClusterRevision : public ReadAttribute {
public:
    ReadAccessControlClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadAccessControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeAccessControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Actions                                                     | 0x0025 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * InstantAction                                                     |   0x00 |
| * InstantActionWithTransition                                       |   0x01 |
| * StartAction                                                       |   0x02 |
| * StartActionWithDuration                                           |   0x03 |
| * StopAction                                                        |   0x04 |
| * PauseAction                                                       |   0x05 |
| * PauseActionWithDuration                                           |   0x06 |
| * ResumeAction                                                      |   0x07 |
| * EnableAction                                                      |   0x08 |
| * EnableActionWithDuration                                          |   0x09 |
| * DisableAction                                                     |   0x0A |
| * DisableActionWithDuration                                         |   0x0B |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * ActionList                                                        | 0x0000 |
| * EndpointLists                                                     | 0x0001 |
| * SetupURL                                                          | 0x0002 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * StateChanged                                                      | 0x0000 |
| * ActionFailed                                                      | 0x0001 |
\*----------------------------------------------------------------------------*/

/*
 * Command InstantAction
 */
class ActionsInstantAction : public ClusterCommand {
public:
    ActionsInstantAction()
        : ClusterCommand("instant-action")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterInstantActionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster instantActionWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::InstantAction::Type mRequest;
};

/*
 * Command InstantActionWithTransition
 */
class ActionsInstantActionWithTransition : public ClusterCommand {
public:
    ActionsInstantActionWithTransition()
        : ClusterCommand("instant-action-with-transition")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterInstantActionWithTransitionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster instantActionWithTransitionWithParams:params
                                                completion:^(NSError * _Nullable error) {
                                                    responsesNeeded--;
                                                    if (error != nil) {
                                                        mError = error;
                                                        LogNSError("Error", error);
                                                    }
                                                    if (responsesNeeded == 0) {
                                                        SetCommandExitStatus(mError);
                                                    }
                                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::InstantActionWithTransition::Type mRequest;
};

/*
 * Command StartAction
 */
class ActionsStartAction : public ClusterCommand {
public:
    ActionsStartAction()
        : ClusterCommand("start-action")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterStartActionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster startActionWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::StartAction::Type mRequest;
};

/*
 * Command StartActionWithDuration
 */
class ActionsStartActionWithDuration : public ClusterCommand {
public:
    ActionsStartActionWithDuration()
        : ClusterCommand("start-action-with-duration")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        AddArgument("Duration", 0, UINT32_MAX, &mRequest.duration);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterStartActionWithDurationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        params.duration = [NSNumber numberWithUnsignedInt:mRequest.duration];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster startActionWithDurationWithParams:params
                                            completion:^(NSError * _Nullable error) {
                                                responsesNeeded--;
                                                if (error != nil) {
                                                    mError = error;
                                                    LogNSError("Error", error);
                                                }
                                                if (responsesNeeded == 0) {
                                                    SetCommandExitStatus(mError);
                                                }
                                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::StartActionWithDuration::Type mRequest;
};

/*
 * Command StopAction
 */
class ActionsStopAction : public ClusterCommand {
public:
    ActionsStopAction()
        : ClusterCommand("stop-action")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterStopActionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stopActionWithParams:params
                               completion:^(NSError * _Nullable error) {
                                   responsesNeeded--;
                                   if (error != nil) {
                                       mError = error;
                                       LogNSError("Error", error);
                                   }
                                   if (responsesNeeded == 0) {
                                       SetCommandExitStatus(mError);
                                   }
                               }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::StopAction::Type mRequest;
};

/*
 * Command PauseAction
 */
class ActionsPauseAction : public ClusterCommand {
public:
    ActionsPauseAction()
        : ClusterCommand("pause-action")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterPauseActionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster pauseActionWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::PauseAction::Type mRequest;
};

/*
 * Command PauseActionWithDuration
 */
class ActionsPauseActionWithDuration : public ClusterCommand {
public:
    ActionsPauseActionWithDuration()
        : ClusterCommand("pause-action-with-duration")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        AddArgument("Duration", 0, UINT32_MAX, &mRequest.duration);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterPauseActionWithDurationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        params.duration = [NSNumber numberWithUnsignedInt:mRequest.duration];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster pauseActionWithDurationWithParams:params
                                            completion:^(NSError * _Nullable error) {
                                                responsesNeeded--;
                                                if (error != nil) {
                                                    mError = error;
                                                    LogNSError("Error", error);
                                                }
                                                if (responsesNeeded == 0) {
                                                    SetCommandExitStatus(mError);
                                                }
                                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::PauseActionWithDuration::Type mRequest;
};

/*
 * Command ResumeAction
 */
class ActionsResumeAction : public ClusterCommand {
public:
    ActionsResumeAction()
        : ClusterCommand("resume-action")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterResumeActionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resumeActionWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::ResumeAction::Type mRequest;
};

/*
 * Command EnableAction
 */
class ActionsEnableAction : public ClusterCommand {
public:
    ActionsEnableAction()
        : ClusterCommand("enable-action")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterEnableActionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enableActionWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::EnableAction::Type mRequest;
};

/*
 * Command EnableActionWithDuration
 */
class ActionsEnableActionWithDuration : public ClusterCommand {
public:
    ActionsEnableActionWithDuration()
        : ClusterCommand("enable-action-with-duration")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        AddArgument("Duration", 0, UINT32_MAX, &mRequest.duration);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterEnableActionWithDurationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        params.duration = [NSNumber numberWithUnsignedInt:mRequest.duration];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enableActionWithDurationWithParams:params
                                             completion:^(NSError * _Nullable error) {
                                                 responsesNeeded--;
                                                 if (error != nil) {
                                                     mError = error;
                                                     LogNSError("Error", error);
                                                 }
                                                 if (responsesNeeded == 0) {
                                                     SetCommandExitStatus(mError);
                                                 }
                                             }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::EnableActionWithDuration::Type mRequest;
};

/*
 * Command DisableAction
 */
class ActionsDisableAction : public ClusterCommand {
public:
    ActionsDisableAction()
        : ClusterCommand("disable-action")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterDisableActionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster disableActionWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::DisableAction::Type mRequest;
};

/*
 * Command DisableActionWithDuration
 */
class ActionsDisableActionWithDuration : public ClusterCommand {
public:
    ActionsDisableActionWithDuration()
        : ClusterCommand("disable-action-with-duration")
    {
        AddArgument("ActionID", 0, UINT16_MAX, &mRequest.actionID);
        AddArgument("InvokeID", 0, UINT32_MAX, &mRequest.invokeID);
        AddArgument("Duration", 0, UINT32_MAX, &mRequest.duration);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) command (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRActionsClusterDisableActionWithDurationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.actionID = [NSNumber numberWithUnsignedShort:mRequest.actionID];
        if (mRequest.invokeID.HasValue()) {
            params.invokeID = [NSNumber numberWithUnsignedInt:mRequest.invokeID.Value()];
        } else {
            params.invokeID = nil;
        }
        params.duration = [NSNumber numberWithUnsignedInt:mRequest.duration];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster disableActionWithDurationWithParams:params
                                              completion:^(NSError * _Nullable error) {
                                                  responsesNeeded--;
                                                  if (error != nil) {
                                                      mError = error;
                                                      LogNSError("Error", error);
                                                  }
                                                  if (responsesNeeded == 0) {
                                                      SetCommandExitStatus(mError);
                                                  }
                                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Actions::Commands::DisableActionWithDuration::Type mRequest;
};

/*
 * Attribute ActionList
 */
class ReadActionsActionList : public ReadAttribute {
public:
    ReadActionsActionList()
        : ReadAttribute("action-list")
    {
    }

    ~ReadActionsActionList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeActionListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.ActionList response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions ActionList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsActionList : public SubscribeAttribute {
public:
    SubscribeAttributeActionsActionList()
        : SubscribeAttribute("action-list")
    {
    }

    ~SubscribeAttributeActionsActionList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActionListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.ActionList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EndpointLists
 */
class ReadActionsEndpointLists : public ReadAttribute {
public:
    ReadActionsEndpointLists()
        : ReadAttribute("endpoint-lists")
    {
    }

    ~ReadActionsEndpointLists() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeEndpointListsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.EndpointLists response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions EndpointLists read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsEndpointLists : public SubscribeAttribute {
public:
    SubscribeAttributeActionsEndpointLists()
        : SubscribeAttribute("endpoint-lists")
    {
    }

    ~SubscribeAttributeActionsEndpointLists() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEndpointListsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.EndpointLists response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SetupURL
 */
class ReadActionsSetupURL : public ReadAttribute {
public:
    ReadActionsSetupURL()
        : ReadAttribute("setup-url")
    {
    }

    ~ReadActionsSetupURL() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeSetupURLWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.SetupURL response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions SetupURL read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsSetupURL : public SubscribeAttribute {
public:
    SubscribeAttributeActionsSetupURL()
        : SubscribeAttribute("setup-url")
    {
    }

    ~SubscribeAttributeActionsSetupURL() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSetupURLWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.SetupURL response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadActionsGeneratedCommandList : public ReadAttribute {
public:
    ReadActionsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadActionsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeActionsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeActionsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadActionsAcceptedCommandList : public ReadAttribute {
public:
    ReadActionsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadActionsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeActionsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeActionsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadActionsAttributeList : public ReadAttribute {
public:
    ReadActionsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadActionsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeActionsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeActionsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadActionsFeatureMap : public ReadAttribute {
public:
    ReadActionsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadActionsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeActionsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeActionsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadActionsClusterRevision : public ReadAttribute {
public:
    ReadActionsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadActionsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeActionsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeActionsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster BasicInformation                                            | 0x0028 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * MfgSpecificPing                                                   |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * DataModelRevision                                                 | 0x0000 |
| * VendorName                                                        | 0x0001 |
| * VendorID                                                          | 0x0002 |
| * ProductName                                                       | 0x0003 |
| * ProductID                                                         | 0x0004 |
| * NodeLabel                                                         | 0x0005 |
| * Location                                                          | 0x0006 |
| * HardwareVersion                                                   | 0x0007 |
| * HardwareVersionString                                             | 0x0008 |
| * SoftwareVersion                                                   | 0x0009 |
| * SoftwareVersionString                                             | 0x000A |
| * ManufacturingDate                                                 | 0x000B |
| * PartNumber                                                        | 0x000C |
| * ProductURL                                                        | 0x000D |
| * ProductLabel                                                      | 0x000E |
| * SerialNumber                                                      | 0x000F |
| * LocalConfigDisabled                                               | 0x0010 |
| * Reachable                                                         | 0x0011 |
| * UniqueID                                                          | 0x0012 |
| * CapabilityMinima                                                  | 0x0013 |
| * ProductAppearance                                                 | 0x0014 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * StartUp                                                           | 0x0000 |
| * ShutDown                                                          | 0x0001 |
| * Leave                                                             | 0x0002 |
| * ReachableChanged                                                  | 0x0003 |
\*----------------------------------------------------------------------------*/

/*
 * Attribute DataModelRevision
 */
class ReadBasicInformationDataModelRevision : public ReadAttribute {
public:
    ReadBasicInformationDataModelRevision()
        : ReadAttribute("data-model-revision")
    {
    }

    ~ReadBasicInformationDataModelRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeDataModelRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.DataModelRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation DataModelRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationDataModelRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationDataModelRevision()
        : SubscribeAttribute("data-model-revision")
    {
    }

    ~SubscribeAttributeBasicInformationDataModelRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDataModelRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.DataModelRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute VendorName
 */
class ReadBasicInformationVendorName : public ReadAttribute {
public:
    ReadBasicInformationVendorName()
        : ReadAttribute("vendor-name")
    {
    }

    ~ReadBasicInformationVendorName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeVendorNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.VendorName response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation VendorName read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationVendorName : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationVendorName()
        : SubscribeAttribute("vendor-name")
    {
    }

    ~SubscribeAttributeBasicInformationVendorName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVendorNameWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.VendorName response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute VendorID
 */
class ReadBasicInformationVendorID : public ReadAttribute {
public:
    ReadBasicInformationVendorID()
        : ReadAttribute("vendor-id")
    {
    }

    ~ReadBasicInformationVendorID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.VendorID response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation VendorID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationVendorID : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationVendorID()
        : SubscribeAttribute("vendor-id")
    {
    }

    ~SubscribeAttributeBasicInformationVendorID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVendorIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.VendorID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductName
 */
class ReadBasicInformationProductName : public ReadAttribute {
public:
    ReadBasicInformationProductName()
        : ReadAttribute("product-name")
    {
    }

    ~ReadBasicInformationProductName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeProductNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.ProductName response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation ProductName read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationProductName : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationProductName()
        : SubscribeAttribute("product-name")
    {
    }

    ~SubscribeAttributeBasicInformationProductName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductNameWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.ProductName response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductID
 */
class ReadBasicInformationProductID : public ReadAttribute {
public:
    ReadBasicInformationProductID()
        : ReadAttribute("product-id")
    {
    }

    ~ReadBasicInformationProductID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeProductIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.ProductID response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation ProductID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationProductID : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationProductID()
        : SubscribeAttribute("product-id")
    {
    }

    ~SubscribeAttributeBasicInformationProductID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.ProductID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NodeLabel
 */
class ReadBasicInformationNodeLabel : public ReadAttribute {
public:
    ReadBasicInformationNodeLabel()
        : ReadAttribute("node-label")
    {
    }

    ~ReadBasicInformationNodeLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeNodeLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.NodeLabel response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation NodeLabel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBasicInformationNodeLabel : public WriteAttribute {
public:
    WriteBasicInformationNodeLabel()
        : WriteAttribute("node-label")
    {
        AddArgument("attr-name", "node-label");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBasicInformationNodeLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) WriteAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeNodeLabelWithValue:value
                                           params:params
                                       completion:^(NSError * _Nullable error) {
                                           if (error != nil) {
                                               LogNSError("BasicInformation NodeLabel write Error", error);
                                           }
                                           SetCommandExitStatus(error);
                                       }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBasicInformationNodeLabel : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationNodeLabel()
        : SubscribeAttribute("node-label")
    {
    }

    ~SubscribeAttributeBasicInformationNodeLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNodeLabelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.NodeLabel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Location
 */
class ReadBasicInformationLocation : public ReadAttribute {
public:
    ReadBasicInformationLocation()
        : ReadAttribute("location")
    {
    }

    ~ReadBasicInformationLocation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeLocationWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.Location response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation Location read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBasicInformationLocation : public WriteAttribute {
public:
    WriteBasicInformationLocation()
        : WriteAttribute("location")
    {
        AddArgument("attr-name", "location");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBasicInformationLocation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) WriteAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeLocationWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("BasicInformation Location write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBasicInformationLocation : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationLocation()
        : SubscribeAttribute("location")
    {
    }

    ~SubscribeAttributeBasicInformationLocation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLocationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.Location response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute HardwareVersion
 */
class ReadBasicInformationHardwareVersion : public ReadAttribute {
public:
    ReadBasicInformationHardwareVersion()
        : ReadAttribute("hardware-version")
    {
    }

    ~ReadBasicInformationHardwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeHardwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.HardwareVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation HardwareVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationHardwareVersion : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationHardwareVersion()
        : SubscribeAttribute("hardware-version")
    {
    }

    ~SubscribeAttributeBasicInformationHardwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeHardwareVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.HardwareVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute HardwareVersionString
 */
class ReadBasicInformationHardwareVersionString : public ReadAttribute {
public:
    ReadBasicInformationHardwareVersionString()
        : ReadAttribute("hardware-version-string")
    {
    }

    ~ReadBasicInformationHardwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeHardwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.HardwareVersionString response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation HardwareVersionString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationHardwareVersionString : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationHardwareVersionString()
        : SubscribeAttribute("hardware-version-string")
    {
    }

    ~SubscribeAttributeBasicInformationHardwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeHardwareVersionStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.HardwareVersionString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SoftwareVersion
 */
class ReadBasicInformationSoftwareVersion : public ReadAttribute {
public:
    ReadBasicInformationSoftwareVersion()
        : ReadAttribute("software-version")
    {
    }

    ~ReadBasicInformationSoftwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeSoftwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.SoftwareVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation SoftwareVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationSoftwareVersion : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationSoftwareVersion()
        : SubscribeAttribute("software-version")
    {
    }

    ~SubscribeAttributeBasicInformationSoftwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSoftwareVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.SoftwareVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SoftwareVersionString
 */
class ReadBasicInformationSoftwareVersionString : public ReadAttribute {
public:
    ReadBasicInformationSoftwareVersionString()
        : ReadAttribute("software-version-string")
    {
    }

    ~ReadBasicInformationSoftwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeSoftwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.SoftwareVersionString response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation SoftwareVersionString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationSoftwareVersionString : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationSoftwareVersionString()
        : SubscribeAttribute("software-version-string")
    {
    }

    ~SubscribeAttributeBasicInformationSoftwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSoftwareVersionStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.SoftwareVersionString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ManufacturingDate
 */
class ReadBasicInformationManufacturingDate : public ReadAttribute {
public:
    ReadBasicInformationManufacturingDate()
        : ReadAttribute("manufacturing-date")
    {
    }

    ~ReadBasicInformationManufacturingDate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeManufacturingDateWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.ManufacturingDate response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation ManufacturingDate read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationManufacturingDate : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationManufacturingDate()
        : SubscribeAttribute("manufacturing-date")
    {
    }

    ~SubscribeAttributeBasicInformationManufacturingDate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeManufacturingDateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.ManufacturingDate response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PartNumber
 */
class ReadBasicInformationPartNumber : public ReadAttribute {
public:
    ReadBasicInformationPartNumber()
        : ReadAttribute("part-number")
    {
    }

    ~ReadBasicInformationPartNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePartNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.PartNumber response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation PartNumber read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationPartNumber : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationPartNumber()
        : SubscribeAttribute("part-number")
    {
    }

    ~SubscribeAttributeBasicInformationPartNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePartNumberWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.PartNumber response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductURL
 */
class ReadBasicInformationProductURL : public ReadAttribute {
public:
    ReadBasicInformationProductURL()
        : ReadAttribute("product-url")
    {
    }

    ~ReadBasicInformationProductURL() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeProductURLWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.ProductURL response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation ProductURL read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationProductURL : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationProductURL()
        : SubscribeAttribute("product-url")
    {
    }

    ~SubscribeAttributeBasicInformationProductURL() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000000D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductURLWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.ProductURL response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductLabel
 */
class ReadBasicInformationProductLabel : public ReadAttribute {
public:
    ReadBasicInformationProductLabel()
        : ReadAttribute("product-label")
    {
    }

    ~ReadBasicInformationProductLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeProductLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.ProductLabel response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation ProductLabel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationProductLabel : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationProductLabel()
        : SubscribeAttribute("product-label")
    {
    }

    ~SubscribeAttributeBasicInformationProductLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000000E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductLabelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.ProductLabel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SerialNumber
 */
class ReadBasicInformationSerialNumber : public ReadAttribute {
public:
    ReadBasicInformationSerialNumber()
        : ReadAttribute("serial-number")
    {
    }

    ~ReadBasicInformationSerialNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeSerialNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.SerialNumber response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation SerialNumber read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationSerialNumber : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationSerialNumber()
        : SubscribeAttribute("serial-number")
    {
    }

    ~SubscribeAttributeBasicInformationSerialNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSerialNumberWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.SerialNumber response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LocalConfigDisabled
 */
class ReadBasicInformationLocalConfigDisabled : public ReadAttribute {
public:
    ReadBasicInformationLocalConfigDisabled()
        : ReadAttribute("local-config-disabled")
    {
    }

    ~ReadBasicInformationLocalConfigDisabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeLocalConfigDisabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.LocalConfigDisabled response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation LocalConfigDisabled read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBasicInformationLocalConfigDisabled : public WriteAttribute {
public:
    WriteBasicInformationLocalConfigDisabled()
        : WriteAttribute("local-config-disabled")
    {
        AddArgument("attr-name", "local-config-disabled");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBasicInformationLocalConfigDisabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) WriteAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeLocalConfigDisabledWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("BasicInformation LocalConfigDisabled write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeBasicInformationLocalConfigDisabled : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationLocalConfigDisabled()
        : SubscribeAttribute("local-config-disabled")
    {
    }

    ~SubscribeAttributeBasicInformationLocalConfigDisabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLocalConfigDisabledWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.LocalConfigDisabled response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Reachable
 */
class ReadBasicInformationReachable : public ReadAttribute {
public:
    ReadBasicInformationReachable()
        : ReadAttribute("reachable")
    {
    }

    ~ReadBasicInformationReachable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeReachableWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.Reachable response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation Reachable read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationReachable : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationReachable()
        : SubscribeAttribute("reachable")
    {
    }

    ~SubscribeAttributeBasicInformationReachable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReachableWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.Reachable response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UniqueID
 */
class ReadBasicInformationUniqueID : public ReadAttribute {
public:
    ReadBasicInformationUniqueID()
        : ReadAttribute("unique-id")
    {
    }

    ~ReadBasicInformationUniqueID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeUniqueIDWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.UniqueID response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation UniqueID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationUniqueID : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationUniqueID()
        : SubscribeAttribute("unique-id")
    {
    }

    ~SubscribeAttributeBasicInformationUniqueID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUniqueIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.UniqueID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CapabilityMinima
 */
class ReadBasicInformationCapabilityMinima : public ReadAttribute {
public:
    ReadBasicInformationCapabilityMinima()
        : ReadAttribute("capability-minima")
    {
    }

    ~ReadBasicInformationCapabilityMinima() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeCapabilityMinimaWithCompletion:^(
            MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.CapabilityMinima response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation CapabilityMinima read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationCapabilityMinima : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationCapabilityMinima()
        : SubscribeAttribute("capability-minima")
    {
    }

    ~SubscribeAttributeBasicInformationCapabilityMinima() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCapabilityMinimaWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRBasicInformationClusterCapabilityMinimaStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.CapabilityMinima response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductAppearance
 */
class ReadBasicInformationProductAppearance : public ReadAttribute {
public:
    ReadBasicInformationProductAppearance()
        : ReadAttribute("product-appearance")
    {
    }

    ~ReadBasicInformationProductAppearance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeProductAppearanceWithCompletion:^(
            MTRBasicInformationClusterProductAppearanceStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.ProductAppearance response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation ProductAppearance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationProductAppearance : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationProductAppearance()
        : SubscribeAttribute("product-appearance")
    {
    }

    ~SubscribeAttributeBasicInformationProductAppearance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductAppearanceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRBasicInformationClusterProductAppearanceStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.ProductAppearance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadBasicInformationGeneratedCommandList : public ReadAttribute {
public:
    ReadBasicInformationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadBasicInformationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeBasicInformationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadBasicInformationAcceptedCommandList : public ReadAttribute {
public:
    ReadBasicInformationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadBasicInformationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeBasicInformationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadBasicInformationAttributeList : public ReadAttribute {
public:
    ReadBasicInformationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadBasicInformationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeBasicInformationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadBasicInformationFeatureMap : public ReadAttribute {
public:
    ReadBasicInformationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadBasicInformationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeBasicInformationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadBasicInformationClusterRevision : public ReadAttribute {
public:
    ReadBasicInformationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadBasicInformationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeBasicInformationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster OtaSoftwareUpdateProvider                                   | 0x0029 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * QueryImage                                                        |   0x00 |
| * ApplyUpdateRequest                                                |   0x02 |
| * NotifyUpdateApplied                                               |   0x04 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command QueryImage
 */
class OtaSoftwareUpdateProviderQueryImage : public ClusterCommand {
public:
    OtaSoftwareUpdateProviderQueryImage()
        : ClusterCommand("query-image")
        , mComplex_ProtocolsSupported(&mRequest.protocolsSupported)
    {
        AddArgument("VendorID", 0, UINT16_MAX, &mRequest.vendorID);
        AddArgument("ProductID", 0, UINT16_MAX, &mRequest.productID);
        AddArgument("SoftwareVersion", 0, UINT32_MAX, &mRequest.softwareVersion);
        AddArgument("ProtocolsSupported", &mComplex_ProtocolsSupported);
        AddArgument("HardwareVersion", 0, UINT16_MAX, &mRequest.hardwareVersion);
        AddArgument("Location", &mRequest.location);
        AddArgument("RequestorCanConsent", 0, 1, &mRequest.requestorCanConsent);
        AddArgument("MetadataForProvider", &mRequest.metadataForProvider);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTROTASoftwareUpdateProviderClusterQueryImageParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.vendorID = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.vendorID)];
        params.productID = [NSNumber numberWithUnsignedShort:mRequest.productID];
        params.softwareVersion = [NSNumber numberWithUnsignedInt:mRequest.softwareVersion];
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.protocolsSupported) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0)];
                [array_0 addObject:newElement_0];
            }
            params.protocolsSupported = array_0;
        }
        if (mRequest.hardwareVersion.HasValue()) {
            params.hardwareVersion = [NSNumber numberWithUnsignedShort:mRequest.hardwareVersion.Value()];
        } else {
            params.hardwareVersion = nil;
        }
        if (mRequest.location.HasValue()) {
            params.location = [[NSString alloc] initWithBytes:mRequest.location.Value().data()
                                                       length:mRequest.location.Value().size()
                                                     encoding:NSUTF8StringEncoding];
        } else {
            params.location = nil;
        }
        if (mRequest.requestorCanConsent.HasValue()) {
            params.requestorCanConsent = [NSNumber numberWithBool:mRequest.requestorCanConsent.Value()];
        } else {
            params.requestorCanConsent = nil;
        }
        if (mRequest.metadataForProvider.HasValue()) {
            params.metadataForProvider = [NSData dataWithBytes:mRequest.metadataForProvider.Value().data()
                                                        length:mRequest.metadataForProvider.Value().size()];
        } else {
            params.metadataForProvider = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster queryImageWithParams:params
                               completion:^(MTROTASoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable values,
                                   NSError * _Nullable error) {
                                   NSLog(@"Values: %@", values);
                                   responsesNeeded--;
                                   if (error != nil) {
                                       mError = error;
                                       LogNSError("Error", error);
                                   }
                                   if (responsesNeeded == 0) {
                                       SetCommandExitStatus(mError);
                                   }
                               }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OtaSoftwareUpdateProvider::Commands::QueryImage::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::OtaSoftwareUpdateProvider::OTADownloadProtocol>>
        mComplex_ProtocolsSupported;
};

/*
 * Command ApplyUpdateRequest
 */
class OtaSoftwareUpdateProviderApplyUpdateRequest : public ClusterCommand {
public:
    OtaSoftwareUpdateProviderApplyUpdateRequest()
        : ClusterCommand("apply-update-request")
    {
        AddArgument("UpdateToken", &mRequest.updateToken);
        AddArgument("NewVersion", 0, UINT32_MAX, &mRequest.newVersion);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTROTASoftwareUpdateProviderClusterApplyUpdateRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.updateToken = [NSData dataWithBytes:mRequest.updateToken.data() length:mRequest.updateToken.size()];
        params.newVersion = [NSNumber numberWithUnsignedInt:mRequest.newVersion];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster applyUpdateRequestWithParams:params
                                       completion:^(MTROTASoftwareUpdateProviderClusterApplyUpdateResponseParams * _Nullable values,
                                           NSError * _Nullable error) {
                                           NSLog(@"Values: %@", values);
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OtaSoftwareUpdateProvider::Commands::ApplyUpdateRequest::Type mRequest;
};

/*
 * Command NotifyUpdateApplied
 */
class OtaSoftwareUpdateProviderNotifyUpdateApplied : public ClusterCommand {
public:
    OtaSoftwareUpdateProviderNotifyUpdateApplied()
        : ClusterCommand("notify-update-applied")
    {
        AddArgument("UpdateToken", &mRequest.updateToken);
        AddArgument("SoftwareVersion", 0, UINT32_MAX, &mRequest.softwareVersion);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTROTASoftwareUpdateProviderClusterNotifyUpdateAppliedParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.updateToken = [NSData dataWithBytes:mRequest.updateToken.data() length:mRequest.updateToken.size()];
        params.softwareVersion = [NSNumber numberWithUnsignedInt:mRequest.softwareVersion];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster notifyUpdateAppliedWithParams:params
                                        completion:^(NSError * _Nullable error) {
                                            responsesNeeded--;
                                            if (error != nil) {
                                                mError = error;
                                                LogNSError("Error", error);
                                            }
                                            if (responsesNeeded == 0) {
                                                SetCommandExitStatus(mError);
                                            }
                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OtaSoftwareUpdateProvider::Commands::NotifyUpdateApplied::Type mRequest;
};

/*
 * Attribute GeneratedCommandList
 */
class ReadOtaSoftwareUpdateProviderGeneratedCommandList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateProviderGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadOtaSoftwareUpdateProviderGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateProvider.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateProvider GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateProviderGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateProviderGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateProviderGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateProvider.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadOtaSoftwareUpdateProviderAcceptedCommandList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateProviderAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadOtaSoftwareUpdateProviderAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateProvider.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateProvider AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateProviderAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateProviderAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateProviderAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateProvider.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadOtaSoftwareUpdateProviderAttributeList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateProviderAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadOtaSoftwareUpdateProviderAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateProvider.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateProvider AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateProviderAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateProviderAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateProviderAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateProvider.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadOtaSoftwareUpdateProviderFeatureMap : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateProviderFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadOtaSoftwareUpdateProviderFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateProvider.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateProvider FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateProviderFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateProviderFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateProviderFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateProvider.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadOtaSoftwareUpdateProviderClusterRevision : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateProviderClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadOtaSoftwareUpdateProviderClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateProvider.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateProvider ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateProviderClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateProviderClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateProviderClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateProvider.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster OtaSoftwareUpdateRequestor                                  | 0x002A |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * AnnounceOTAProvider                                               |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * DefaultOTAProviders                                               | 0x0000 |
| * UpdatePossible                                                    | 0x0001 |
| * UpdateState                                                       | 0x0002 |
| * UpdateStateProgress                                               | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * StateTransition                                                   | 0x0000 |
| * VersionApplied                                                    | 0x0001 |
| * DownloadError                                                     | 0x0002 |
\*----------------------------------------------------------------------------*/

/*
 * Command AnnounceOTAProvider
 */
class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand {
public:
    OtaSoftwareUpdateRequestorAnnounceOTAProvider()
        : ClusterCommand("announce-otaprovider")
    {
        AddArgument("ProviderNodeID", 0, UINT64_MAX, &mRequest.providerNodeID);
        AddArgument("VendorID", 0, UINT16_MAX, &mRequest.vendorID);
        AddArgument("AnnouncementReason", 0, UINT8_MAX, &mRequest.announcementReason);
        AddArgument("MetadataForNode", &mRequest.metadataForNode);
        AddArgument("Endpoint", 0, UINT16_MAX, &mRequest.endpoint);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTROTASoftwareUpdateRequestorClusterAnnounceOTAProviderParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.providerNodeID = [NSNumber numberWithUnsignedLongLong:mRequest.providerNodeID];
        params.vendorID = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.vendorID)];
        params.announcementReason = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.announcementReason)];
        if (mRequest.metadataForNode.HasValue()) {
            params.metadataForNode = [NSData dataWithBytes:mRequest.metadataForNode.Value().data()
                                                    length:mRequest.metadataForNode.Value().size()];
        } else {
            params.metadataForNode = nil;
        }
        params.endpoint = [NSNumber numberWithUnsignedShort:mRequest.endpoint];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster announceOTAProviderWithParams:params
                                        completion:^(NSError * _Nullable error) {
                                            responsesNeeded--;
                                            if (error != nil) {
                                                mError = error;
                                                LogNSError("Error", error);
                                            }
                                            if (responsesNeeded == 0) {
                                                SetCommandExitStatus(mError);
                                            }
                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OtaSoftwareUpdateRequestor::Commands::AnnounceOTAProvider::Type mRequest;
};

/*
 * Attribute DefaultOTAProviders
 */
class ReadOtaSoftwareUpdateRequestorDefaultOTAProviders : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorDefaultOTAProviders()
        : ReadAttribute("default-otaproviders")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorDefaultOTAProviders() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster
            readAttributeDefaultOTAProvidersWithParams:params
                                            completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                NSLog(@"OTASoftwareUpdateRequestor.DefaultOTAProviders response %@",
                                                    [value description]);
                                                if (error != nil) {
                                                    LogNSError("OTASoftwareUpdateRequestor DefaultOTAProviders read Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }
};

class WriteOtaSoftwareUpdateRequestorDefaultOTAProviders : public WriteAttribute {
public:
    WriteOtaSoftwareUpdateRequestorDefaultOTAProviders()
        : WriteAttribute("default-otaproviders")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "default-otaproviders");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteOtaSoftwareUpdateRequestorDefaultOTAProviders() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTROTASoftwareUpdateRequestorClusterProviderLocation * newElement_0;
                newElement_0 = [MTROTASoftwareUpdateRequestorClusterProviderLocation new];
                newElement_0.providerNodeID = [NSNumber numberWithUnsignedLongLong:entry_0.providerNodeID];
                newElement_0.endpoint = [NSNumber numberWithUnsignedShort:entry_0.endpoint];
                newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster
            writeAttributeDefaultOTAProvidersWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("OTASoftwareUpdateRequestor DefaultOTAProviders write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::Type> mValue;
    TypedComplexArgument<
        chip::app::DataModel::List<const chip::app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::Type>>
        mComplex;
};

class SubscribeAttributeOtaSoftwareUpdateRequestorDefaultOTAProviders : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorDefaultOTAProviders()
        : SubscribeAttribute("default-otaproviders")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorDefaultOTAProviders() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDefaultOTAProvidersWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.DefaultOTAProviders response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UpdatePossible
 */
class ReadOtaSoftwareUpdateRequestorUpdatePossible : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorUpdatePossible()
        : ReadAttribute("update-possible")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorUpdatePossible() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeUpdatePossibleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.UpdatePossible response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor UpdatePossible read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorUpdatePossible : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorUpdatePossible()
        : SubscribeAttribute("update-possible")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorUpdatePossible() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUpdatePossibleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.UpdatePossible response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UpdateState
 */
class ReadOtaSoftwareUpdateRequestorUpdateState : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorUpdateState()
        : ReadAttribute("update-state")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorUpdateState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeUpdateStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.UpdateState response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor UpdateState read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorUpdateState : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorUpdateState()
        : SubscribeAttribute("update-state")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorUpdateState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUpdateStateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.UpdateState response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UpdateStateProgress
 */
class ReadOtaSoftwareUpdateRequestorUpdateStateProgress : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorUpdateStateProgress()
        : ReadAttribute("update-state-progress")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorUpdateStateProgress() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeUpdateStateProgressWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.UpdateStateProgress response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor UpdateStateProgress read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorUpdateStateProgress : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorUpdateStateProgress()
        : SubscribeAttribute("update-state-progress")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorUpdateStateProgress() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUpdateStateProgressWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.UpdateStateProgress response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadOtaSoftwareUpdateRequestorGeneratedCommandList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadOtaSoftwareUpdateRequestorAcceptedCommandList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadOtaSoftwareUpdateRequestorAttributeList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadOtaSoftwareUpdateRequestorFeatureMap : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadOtaSoftwareUpdateRequestorClusterRevision : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster LocalizationConfiguration                                   | 0x002B |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * ActiveLocale                                                      | 0x0000 |
| * SupportedLocales                                                  | 0x0001 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute ActiveLocale
 */
class ReadLocalizationConfigurationActiveLocale : public ReadAttribute {
public:
    ReadLocalizationConfigurationActiveLocale()
        : ReadAttribute("active-locale")
    {
    }

    ~ReadLocalizationConfigurationActiveLocale() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeActiveLocaleWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.ActiveLocale response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration ActiveLocale read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteLocalizationConfigurationActiveLocale : public WriteAttribute {
public:
    WriteLocalizationConfigurationActiveLocale()
        : WriteAttribute("active-locale")
    {
        AddArgument("attr-name", "active-locale");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteLocalizationConfigurationActiveLocale() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeActiveLocaleWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("LocalizationConfiguration ActiveLocale write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeLocalizationConfigurationActiveLocale : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationActiveLocale()
        : SubscribeAttribute("active-locale")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationActiveLocale() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveLocaleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.ActiveLocale response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SupportedLocales
 */
class ReadLocalizationConfigurationSupportedLocales : public ReadAttribute {
public:
    ReadLocalizationConfigurationSupportedLocales()
        : ReadAttribute("supported-locales")
    {
    }

    ~ReadLocalizationConfigurationSupportedLocales() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeSupportedLocalesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.SupportedLocales response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration SupportedLocales read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLocalizationConfigurationSupportedLocales : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationSupportedLocales()
        : SubscribeAttribute("supported-locales")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationSupportedLocales() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSupportedLocalesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.SupportedLocales response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadLocalizationConfigurationGeneratedCommandList : public ReadAttribute {
public:
    ReadLocalizationConfigurationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadLocalizationConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLocalizationConfigurationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadLocalizationConfigurationAcceptedCommandList : public ReadAttribute {
public:
    ReadLocalizationConfigurationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadLocalizationConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLocalizationConfigurationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadLocalizationConfigurationAttributeList : public ReadAttribute {
public:
    ReadLocalizationConfigurationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadLocalizationConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLocalizationConfigurationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadLocalizationConfigurationFeatureMap : public ReadAttribute {
public:
    ReadLocalizationConfigurationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadLocalizationConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLocalizationConfigurationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadLocalizationConfigurationClusterRevision : public ReadAttribute {
public:
    ReadLocalizationConfigurationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadLocalizationConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLocalizationConfigurationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device
                                                                                     endpointID:@(endpointId)
                                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster TimeFormatLocalization                                      | 0x002C |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * HourFormat                                                        | 0x0000 |
| * ActiveCalendarType                                                | 0x0001 |
| * SupportedCalendarTypes                                            | 0x0002 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute HourFormat
 */
class ReadTimeFormatLocalizationHourFormat : public ReadAttribute {
public:
    ReadTimeFormatLocalizationHourFormat()
        : ReadAttribute("hour-format")
    {
    }

    ~ReadTimeFormatLocalizationHourFormat() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeHourFormatWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.HourFormat response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization HourFormat read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteTimeFormatLocalizationHourFormat : public WriteAttribute {
public:
    WriteTimeFormatLocalizationHourFormat()
        : WriteAttribute("hour-format")
    {
        AddArgument("attr-name", "hour-format");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteTimeFormatLocalizationHourFormat() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeHourFormatWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("TimeFormatLocalization HourFormat write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeTimeFormatLocalizationHourFormat : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationHourFormat()
        : SubscribeAttribute("hour-format")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationHourFormat() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeHourFormatWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.HourFormat response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveCalendarType
 */
class ReadTimeFormatLocalizationActiveCalendarType : public ReadAttribute {
public:
    ReadTimeFormatLocalizationActiveCalendarType()
        : ReadAttribute("active-calendar-type")
    {
    }

    ~ReadTimeFormatLocalizationActiveCalendarType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeActiveCalendarTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.ActiveCalendarType response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization ActiveCalendarType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteTimeFormatLocalizationActiveCalendarType : public WriteAttribute {
public:
    WriteTimeFormatLocalizationActiveCalendarType()
        : WriteAttribute("active-calendar-type")
    {
        AddArgument("attr-name", "active-calendar-type");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteTimeFormatLocalizationActiveCalendarType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) WriteAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeActiveCalendarTypeWithValue:value
                                                    params:params
                                                completion:^(NSError * _Nullable error) {
                                                    if (error != nil) {
                                                        LogNSError("TimeFormatLocalization ActiveCalendarType write Error", error);
                                                    }
                                                    SetCommandExitStatus(error);
                                                }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeTimeFormatLocalizationActiveCalendarType : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationActiveCalendarType()
        : SubscribeAttribute("active-calendar-type")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationActiveCalendarType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveCalendarTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.ActiveCalendarType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SupportedCalendarTypes
 */
class ReadTimeFormatLocalizationSupportedCalendarTypes : public ReadAttribute {
public:
    ReadTimeFormatLocalizationSupportedCalendarTypes()
        : ReadAttribute("supported-calendar-types")
    {
    }

    ~ReadTimeFormatLocalizationSupportedCalendarTypes() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeSupportedCalendarTypesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.SupportedCalendarTypes response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization SupportedCalendarTypes read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTimeFormatLocalizationSupportedCalendarTypes : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationSupportedCalendarTypes()
        : SubscribeAttribute("supported-calendar-types")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationSupportedCalendarTypes() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSupportedCalendarTypesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.SupportedCalendarTypes response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadTimeFormatLocalizationGeneratedCommandList : public ReadAttribute {
public:
    ReadTimeFormatLocalizationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadTimeFormatLocalizationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTimeFormatLocalizationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadTimeFormatLocalizationAcceptedCommandList : public ReadAttribute {
public:
    ReadTimeFormatLocalizationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadTimeFormatLocalizationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTimeFormatLocalizationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadTimeFormatLocalizationAttributeList : public ReadAttribute {
public:
    ReadTimeFormatLocalizationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadTimeFormatLocalizationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTimeFormatLocalizationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadTimeFormatLocalizationFeatureMap : public ReadAttribute {
public:
    ReadTimeFormatLocalizationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadTimeFormatLocalizationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTimeFormatLocalizationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadTimeFormatLocalizationClusterRevision : public ReadAttribute {
public:
    ReadTimeFormatLocalizationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadTimeFormatLocalizationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTimeFormatLocalizationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster UnitLocalization                                            | 0x002D |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * TemperatureUnit                                                   | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute TemperatureUnit
 */
class ReadUnitLocalizationTemperatureUnit : public ReadAttribute {
public:
    ReadUnitLocalizationTemperatureUnit()
        : ReadAttribute("temperature-unit")
    {
    }

    ~ReadUnitLocalizationTemperatureUnit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeTemperatureUnitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitLocalization.TemperatureUnit response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitLocalization TemperatureUnit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitLocalizationTemperatureUnit : public WriteAttribute {
public:
    WriteUnitLocalizationTemperatureUnit()
        : WriteAttribute("temperature-unit")
    {
        AddArgument("attr-name", "temperature-unit");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitLocalizationTemperatureUnit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeTemperatureUnitWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("UnitLocalization TemperatureUnit write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitLocalizationTemperatureUnit : public SubscribeAttribute {
public:
    SubscribeAttributeUnitLocalizationTemperatureUnit()
        : SubscribeAttribute("temperature-unit")
    {
    }

    ~SubscribeAttributeUnitLocalizationTemperatureUnit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTemperatureUnitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitLocalization.TemperatureUnit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadUnitLocalizationGeneratedCommandList : public ReadAttribute {
public:
    ReadUnitLocalizationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadUnitLocalizationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitLocalization.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitLocalization GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitLocalizationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitLocalizationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeUnitLocalizationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitLocalization.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadUnitLocalizationAcceptedCommandList : public ReadAttribute {
public:
    ReadUnitLocalizationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadUnitLocalizationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitLocalization.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitLocalization AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitLocalizationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitLocalizationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeUnitLocalizationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitLocalization.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadUnitLocalizationAttributeList : public ReadAttribute {
public:
    ReadUnitLocalizationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadUnitLocalizationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitLocalization.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitLocalization AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitLocalizationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitLocalizationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeUnitLocalizationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitLocalization.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadUnitLocalizationFeatureMap : public ReadAttribute {
public:
    ReadUnitLocalizationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadUnitLocalizationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitLocalization.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitLocalization FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitLocalizationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeUnitLocalizationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeUnitLocalizationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitLocalization.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadUnitLocalizationClusterRevision : public ReadAttribute {
public:
    ReadUnitLocalizationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadUnitLocalizationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitLocalization.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitLocalization ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitLocalizationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeUnitLocalizationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeUnitLocalizationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitLocalization.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster PowerSourceConfiguration                                    | 0x002E |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Sources                                                           | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute Sources
 */
class ReadPowerSourceConfigurationSources : public ReadAttribute {
public:
    ReadPowerSourceConfigurationSources()
        : ReadAttribute("sources")
    {
    }

    ~ReadPowerSourceConfigurationSources() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeSourcesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSourceConfiguration.Sources response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSourceConfiguration Sources read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceConfigurationSources : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceConfigurationSources()
        : SubscribeAttribute("sources")
    {
    }

    ~SubscribeAttributePowerSourceConfigurationSources() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSourcesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSourceConfiguration.Sources response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadPowerSourceConfigurationGeneratedCommandList : public ReadAttribute {
public:
    ReadPowerSourceConfigurationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadPowerSourceConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSourceConfiguration.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSourceConfiguration GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceConfigurationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceConfigurationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributePowerSourceConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSourceConfiguration.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadPowerSourceConfigurationAcceptedCommandList : public ReadAttribute {
public:
    ReadPowerSourceConfigurationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadPowerSourceConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSourceConfiguration.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSourceConfiguration AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceConfigurationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceConfigurationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributePowerSourceConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSourceConfiguration.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadPowerSourceConfigurationAttributeList : public ReadAttribute {
public:
    ReadPowerSourceConfigurationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadPowerSourceConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSourceConfiguration.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSourceConfiguration AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceConfigurationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceConfigurationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributePowerSourceConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSourceConfiguration.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadPowerSourceConfigurationFeatureMap : public ReadAttribute {
public:
    ReadPowerSourceConfigurationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadPowerSourceConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSourceConfiguration.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSourceConfiguration FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceConfigurationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceConfigurationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributePowerSourceConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSourceConfiguration.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadPowerSourceConfigurationClusterRevision : public ReadAttribute {
public:
    ReadPowerSourceConfigurationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadPowerSourceConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSourceConfiguration.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSourceConfiguration ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceConfigurationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceConfigurationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributePowerSourceConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSourceConfiguration.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster PowerSource                                                 | 0x002F |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Status                                                            | 0x0000 |
| * Order                                                             | 0x0001 |
| * Description                                                       | 0x0002 |
| * WiredAssessedInputVoltage                                         | 0x0003 |
| * WiredAssessedInputFrequency                                       | 0x0004 |
| * WiredCurrentType                                                  | 0x0005 |
| * WiredAssessedCurrent                                              | 0x0006 |
| * WiredNominalVoltage                                               | 0x0007 |
| * WiredMaximumCurrent                                               | 0x0008 |
| * WiredPresent                                                      | 0x0009 |
| * ActiveWiredFaults                                                 | 0x000A |
| * BatVoltage                                                        | 0x000B |
| * BatPercentRemaining                                               | 0x000C |
| * BatTimeRemaining                                                  | 0x000D |
| * BatChargeLevel                                                    | 0x000E |
| * BatReplacementNeeded                                              | 0x000F |
| * BatReplaceability                                                 | 0x0010 |
| * BatPresent                                                        | 0x0011 |
| * ActiveBatFaults                                                   | 0x0012 |
| * BatReplacementDescription                                         | 0x0013 |
| * BatCommonDesignation                                              | 0x0014 |
| * BatANSIDesignation                                                | 0x0015 |
| * BatIECDesignation                                                 | 0x0016 |
| * BatApprovedChemistry                                              | 0x0017 |
| * BatCapacity                                                       | 0x0018 |
| * BatQuantity                                                       | 0x0019 |
| * BatChargeState                                                    | 0x001A |
| * BatTimeToFullCharge                                               | 0x001B |
| * BatFunctionalWhileCharging                                        | 0x001C |
| * BatChargingCurrent                                                | 0x001D |
| * ActiveBatChargeFaults                                             | 0x001E |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * WiredFaultChange                                                  | 0x0000 |
| * BatFaultChange                                                    | 0x0001 |
| * BatChargeFaultChange                                              | 0x0002 |
\*----------------------------------------------------------------------------*/

/*
 * Attribute Status
 */
class ReadPowerSourceStatus : public ReadAttribute {
public:
    ReadPowerSourceStatus()
        : ReadAttribute("status")
    {
    }

    ~ReadPowerSourceStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.Status response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource Status read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceStatus : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceStatus()
        : SubscribeAttribute("status")
    {
    }

    ~SubscribeAttributePowerSourceStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.Status response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Order
 */
class ReadPowerSourceOrder : public ReadAttribute {
public:
    ReadPowerSourceOrder()
        : ReadAttribute("order")
    {
    }

    ~ReadPowerSourceOrder() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeOrderWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.Order response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource Order read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceOrder : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceOrder()
        : SubscribeAttribute("order")
    {
    }

    ~SubscribeAttributePowerSourceOrder() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOrderWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.Order response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Description
 */
class ReadPowerSourceDescription : public ReadAttribute {
public:
    ReadPowerSourceDescription()
        : ReadAttribute("description")
    {
    }

    ~ReadPowerSourceDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.Description response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource Description read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceDescription : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceDescription()
        : SubscribeAttribute("description")
    {
    }

    ~SubscribeAttributePowerSourceDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDescriptionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.Description response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiredAssessedInputVoltage
 */
class ReadPowerSourceWiredAssessedInputVoltage : public ReadAttribute {
public:
    ReadPowerSourceWiredAssessedInputVoltage()
        : ReadAttribute("wired-assessed-input-voltage")
    {
    }

    ~ReadPowerSourceWiredAssessedInputVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWiredAssessedInputVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.WiredAssessedInputVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource WiredAssessedInputVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceWiredAssessedInputVoltage : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceWiredAssessedInputVoltage()
        : SubscribeAttribute("wired-assessed-input-voltage")
    {
    }

    ~SubscribeAttributePowerSourceWiredAssessedInputVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiredAssessedInputVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.WiredAssessedInputVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiredAssessedInputFrequency
 */
class ReadPowerSourceWiredAssessedInputFrequency : public ReadAttribute {
public:
    ReadPowerSourceWiredAssessedInputFrequency()
        : ReadAttribute("wired-assessed-input-frequency")
    {
    }

    ~ReadPowerSourceWiredAssessedInputFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWiredAssessedInputFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.WiredAssessedInputFrequency response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource WiredAssessedInputFrequency read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceWiredAssessedInputFrequency : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceWiredAssessedInputFrequency()
        : SubscribeAttribute("wired-assessed-input-frequency")
    {
    }

    ~SubscribeAttributePowerSourceWiredAssessedInputFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiredAssessedInputFrequencyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.WiredAssessedInputFrequency response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiredCurrentType
 */
class ReadPowerSourceWiredCurrentType : public ReadAttribute {
public:
    ReadPowerSourceWiredCurrentType()
        : ReadAttribute("wired-current-type")
    {
    }

    ~ReadPowerSourceWiredCurrentType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWiredCurrentTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.WiredCurrentType response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource WiredCurrentType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceWiredCurrentType : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceWiredCurrentType()
        : SubscribeAttribute("wired-current-type")
    {
    }

    ~SubscribeAttributePowerSourceWiredCurrentType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiredCurrentTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.WiredCurrentType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiredAssessedCurrent
 */
class ReadPowerSourceWiredAssessedCurrent : public ReadAttribute {
public:
    ReadPowerSourceWiredAssessedCurrent()
        : ReadAttribute("wired-assessed-current")
    {
    }

    ~ReadPowerSourceWiredAssessedCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWiredAssessedCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.WiredAssessedCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource WiredAssessedCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceWiredAssessedCurrent : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceWiredAssessedCurrent()
        : SubscribeAttribute("wired-assessed-current")
    {
    }

    ~SubscribeAttributePowerSourceWiredAssessedCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiredAssessedCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.WiredAssessedCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiredNominalVoltage
 */
class ReadPowerSourceWiredNominalVoltage : public ReadAttribute {
public:
    ReadPowerSourceWiredNominalVoltage()
        : ReadAttribute("wired-nominal-voltage")
    {
    }

    ~ReadPowerSourceWiredNominalVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWiredNominalVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.WiredNominalVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource WiredNominalVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceWiredNominalVoltage : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceWiredNominalVoltage()
        : SubscribeAttribute("wired-nominal-voltage")
    {
    }

    ~SubscribeAttributePowerSourceWiredNominalVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiredNominalVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.WiredNominalVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiredMaximumCurrent
 */
class ReadPowerSourceWiredMaximumCurrent : public ReadAttribute {
public:
    ReadPowerSourceWiredMaximumCurrent()
        : ReadAttribute("wired-maximum-current")
    {
    }

    ~ReadPowerSourceWiredMaximumCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWiredMaximumCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.WiredMaximumCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource WiredMaximumCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceWiredMaximumCurrent : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceWiredMaximumCurrent()
        : SubscribeAttribute("wired-maximum-current")
    {
    }

    ~SubscribeAttributePowerSourceWiredMaximumCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiredMaximumCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.WiredMaximumCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiredPresent
 */
class ReadPowerSourceWiredPresent : public ReadAttribute {
public:
    ReadPowerSourceWiredPresent()
        : ReadAttribute("wired-present")
    {
    }

    ~ReadPowerSourceWiredPresent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWiredPresentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.WiredPresent response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource WiredPresent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceWiredPresent : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceWiredPresent()
        : SubscribeAttribute("wired-present")
    {
    }

    ~SubscribeAttributePowerSourceWiredPresent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiredPresentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.WiredPresent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveWiredFaults
 */
class ReadPowerSourceActiveWiredFaults : public ReadAttribute {
public:
    ReadPowerSourceActiveWiredFaults()
        : ReadAttribute("active-wired-faults")
    {
    }

    ~ReadPowerSourceActiveWiredFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeActiveWiredFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.ActiveWiredFaults response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource ActiveWiredFaults read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceActiveWiredFaults : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceActiveWiredFaults()
        : SubscribeAttribute("active-wired-faults")
    {
    }

    ~SubscribeAttributePowerSourceActiveWiredFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveWiredFaultsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.ActiveWiredFaults response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatVoltage
 */
class ReadPowerSourceBatVoltage : public ReadAttribute {
public:
    ReadPowerSourceBatVoltage()
        : ReadAttribute("bat-voltage")
    {
    }

    ~ReadPowerSourceBatVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatVoltage : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatVoltage()
        : SubscribeAttribute("bat-voltage")
    {
    }

    ~SubscribeAttributePowerSourceBatVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatPercentRemaining
 */
class ReadPowerSourceBatPercentRemaining : public ReadAttribute {
public:
    ReadPowerSourceBatPercentRemaining()
        : ReadAttribute("bat-percent-remaining")
    {
    }

    ~ReadPowerSourceBatPercentRemaining() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatPercentRemainingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatPercentRemaining response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatPercentRemaining read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatPercentRemaining : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatPercentRemaining()
        : SubscribeAttribute("bat-percent-remaining")
    {
    }

    ~SubscribeAttributePowerSourceBatPercentRemaining() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatPercentRemainingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatPercentRemaining response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatTimeRemaining
 */
class ReadPowerSourceBatTimeRemaining : public ReadAttribute {
public:
    ReadPowerSourceBatTimeRemaining()
        : ReadAttribute("bat-time-remaining")
    {
    }

    ~ReadPowerSourceBatTimeRemaining() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatTimeRemainingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatTimeRemaining response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatTimeRemaining read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatTimeRemaining : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatTimeRemaining()
        : SubscribeAttribute("bat-time-remaining")
    {
    }

    ~SubscribeAttributePowerSourceBatTimeRemaining() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000000D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatTimeRemainingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatTimeRemaining response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatChargeLevel
 */
class ReadPowerSourceBatChargeLevel : public ReadAttribute {
public:
    ReadPowerSourceBatChargeLevel()
        : ReadAttribute("bat-charge-level")
    {
    }

    ~ReadPowerSourceBatChargeLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatChargeLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatChargeLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatChargeLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatChargeLevel : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatChargeLevel()
        : SubscribeAttribute("bat-charge-level")
    {
    }

    ~SubscribeAttributePowerSourceBatChargeLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000000E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatChargeLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatChargeLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatReplacementNeeded
 */
class ReadPowerSourceBatReplacementNeeded : public ReadAttribute {
public:
    ReadPowerSourceBatReplacementNeeded()
        : ReadAttribute("bat-replacement-needed")
    {
    }

    ~ReadPowerSourceBatReplacementNeeded() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatReplacementNeededWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatReplacementNeeded response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatReplacementNeeded read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatReplacementNeeded : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatReplacementNeeded()
        : SubscribeAttribute("bat-replacement-needed")
    {
    }

    ~SubscribeAttributePowerSourceBatReplacementNeeded() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatReplacementNeededWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatReplacementNeeded response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatReplaceability
 */
class ReadPowerSourceBatReplaceability : public ReadAttribute {
public:
    ReadPowerSourceBatReplaceability()
        : ReadAttribute("bat-replaceability")
    {
    }

    ~ReadPowerSourceBatReplaceability() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatReplaceabilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatReplaceability response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatReplaceability read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatReplaceability : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatReplaceability()
        : SubscribeAttribute("bat-replaceability")
    {
    }

    ~SubscribeAttributePowerSourceBatReplaceability() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatReplaceabilityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatReplaceability response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatPresent
 */
class ReadPowerSourceBatPresent : public ReadAttribute {
public:
    ReadPowerSourceBatPresent()
        : ReadAttribute("bat-present")
    {
    }

    ~ReadPowerSourceBatPresent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatPresentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatPresent response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatPresent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatPresent : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatPresent()
        : SubscribeAttribute("bat-present")
    {
    }

    ~SubscribeAttributePowerSourceBatPresent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatPresentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatPresent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveBatFaults
 */
class ReadPowerSourceActiveBatFaults : public ReadAttribute {
public:
    ReadPowerSourceActiveBatFaults()
        : ReadAttribute("active-bat-faults")
    {
    }

    ~ReadPowerSourceActiveBatFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeActiveBatFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.ActiveBatFaults response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource ActiveBatFaults read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceActiveBatFaults : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceActiveBatFaults()
        : SubscribeAttribute("active-bat-faults")
    {
    }

    ~SubscribeAttributePowerSourceActiveBatFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveBatFaultsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.ActiveBatFaults response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatReplacementDescription
 */
class ReadPowerSourceBatReplacementDescription : public ReadAttribute {
public:
    ReadPowerSourceBatReplacementDescription()
        : ReadAttribute("bat-replacement-description")
    {
    }

    ~ReadPowerSourceBatReplacementDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatReplacementDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatReplacementDescription response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatReplacementDescription read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatReplacementDescription : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatReplacementDescription()
        : SubscribeAttribute("bat-replacement-description")
    {
    }

    ~SubscribeAttributePowerSourceBatReplacementDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatReplacementDescriptionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatReplacementDescription response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatCommonDesignation
 */
class ReadPowerSourceBatCommonDesignation : public ReadAttribute {
public:
    ReadPowerSourceBatCommonDesignation()
        : ReadAttribute("bat-common-designation")
    {
    }

    ~ReadPowerSourceBatCommonDesignation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatCommonDesignationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatCommonDesignation response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatCommonDesignation read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatCommonDesignation : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatCommonDesignation()
        : SubscribeAttribute("bat-common-designation")
    {
    }

    ~SubscribeAttributePowerSourceBatCommonDesignation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatCommonDesignationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatCommonDesignation response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatANSIDesignation
 */
class ReadPowerSourceBatANSIDesignation : public ReadAttribute {
public:
    ReadPowerSourceBatANSIDesignation()
        : ReadAttribute("bat-ansidesignation")
    {
    }

    ~ReadPowerSourceBatANSIDesignation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatANSIDesignationWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatANSIDesignation response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatANSIDesignation read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatANSIDesignation : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatANSIDesignation()
        : SubscribeAttribute("bat-ansidesignation")
    {
    }

    ~SubscribeAttributePowerSourceBatANSIDesignation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatANSIDesignationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatANSIDesignation response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatIECDesignation
 */
class ReadPowerSourceBatIECDesignation : public ReadAttribute {
public:
    ReadPowerSourceBatIECDesignation()
        : ReadAttribute("bat-iecdesignation")
    {
    }

    ~ReadPowerSourceBatIECDesignation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatIECDesignationWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatIECDesignation response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatIECDesignation read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatIECDesignation : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatIECDesignation()
        : SubscribeAttribute("bat-iecdesignation")
    {
    }

    ~SubscribeAttributePowerSourceBatIECDesignation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatIECDesignationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatIECDesignation response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatApprovedChemistry
 */
class ReadPowerSourceBatApprovedChemistry : public ReadAttribute {
public:
    ReadPowerSourceBatApprovedChemistry()
        : ReadAttribute("bat-approved-chemistry")
    {
    }

    ~ReadPowerSourceBatApprovedChemistry() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatApprovedChemistryWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatApprovedChemistry response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatApprovedChemistry read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatApprovedChemistry : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatApprovedChemistry()
        : SubscribeAttribute("bat-approved-chemistry")
    {
    }

    ~SubscribeAttributePowerSourceBatApprovedChemistry() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatApprovedChemistryWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatApprovedChemistry response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatCapacity
 */
class ReadPowerSourceBatCapacity : public ReadAttribute {
public:
    ReadPowerSourceBatCapacity()
        : ReadAttribute("bat-capacity")
    {
    }

    ~ReadPowerSourceBatCapacity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000018) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatCapacityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatCapacity response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatCapacity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatCapacity : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatCapacity()
        : SubscribeAttribute("bat-capacity")
    {
    }

    ~SubscribeAttributePowerSourceBatCapacity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatCapacityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatCapacity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatQuantity
 */
class ReadPowerSourceBatQuantity : public ReadAttribute {
public:
    ReadPowerSourceBatQuantity()
        : ReadAttribute("bat-quantity")
    {
    }

    ~ReadPowerSourceBatQuantity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x00000019) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatQuantityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatQuantity response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatQuantity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatQuantity : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatQuantity()
        : SubscribeAttribute("bat-quantity")
    {
    }

    ~SubscribeAttributePowerSourceBatQuantity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatQuantityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatQuantity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatChargeState
 */
class ReadPowerSourceBatChargeState : public ReadAttribute {
public:
    ReadPowerSourceBatChargeState()
        : ReadAttribute("bat-charge-state")
    {
    }

    ~ReadPowerSourceBatChargeState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatChargeStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatChargeState response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatChargeState read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatChargeState : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatChargeState()
        : SubscribeAttribute("bat-charge-state")
    {
    }

    ~SubscribeAttributePowerSourceBatChargeState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatChargeStateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatChargeState response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatTimeToFullCharge
 */
class ReadPowerSourceBatTimeToFullCharge : public ReadAttribute {
public:
    ReadPowerSourceBatTimeToFullCharge()
        : ReadAttribute("bat-time-to-full-charge")
    {
    }

    ~ReadPowerSourceBatTimeToFullCharge() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000001B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatTimeToFullChargeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatTimeToFullCharge response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatTimeToFullCharge read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatTimeToFullCharge : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatTimeToFullCharge()
        : SubscribeAttribute("bat-time-to-full-charge")
    {
    }

    ~SubscribeAttributePowerSourceBatTimeToFullCharge() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatTimeToFullChargeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatTimeToFullCharge response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatFunctionalWhileCharging
 */
class ReadPowerSourceBatFunctionalWhileCharging : public ReadAttribute {
public:
    ReadPowerSourceBatFunctionalWhileCharging()
        : ReadAttribute("bat-functional-while-charging")
    {
    }

    ~ReadPowerSourceBatFunctionalWhileCharging() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000001C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatFunctionalWhileChargingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatFunctionalWhileCharging response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatFunctionalWhileCharging read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatFunctionalWhileCharging : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatFunctionalWhileCharging()
        : SubscribeAttribute("bat-functional-while-charging")
    {
    }

    ~SubscribeAttributePowerSourceBatFunctionalWhileCharging() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatFunctionalWhileChargingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatFunctionalWhileCharging response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatChargingCurrent
 */
class ReadPowerSourceBatChargingCurrent : public ReadAttribute {
public:
    ReadPowerSourceBatChargingCurrent()
        : ReadAttribute("bat-charging-current")
    {
    }

    ~ReadPowerSourceBatChargingCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000001D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBatChargingCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.BatChargingCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource BatChargingCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceBatChargingCurrent : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceBatChargingCurrent()
        : SubscribeAttribute("bat-charging-current")
    {
    }

    ~SubscribeAttributePowerSourceBatChargingCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000001D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBatChargingCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.BatChargingCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveBatChargeFaults
 */
class ReadPowerSourceActiveBatChargeFaults : public ReadAttribute {
public:
    ReadPowerSourceActiveBatChargeFaults()
        : ReadAttribute("active-bat-charge-faults")
    {
    }

    ~ReadPowerSourceActiveBatChargeFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000001E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeActiveBatChargeFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.ActiveBatChargeFaults response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource ActiveBatChargeFaults read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceActiveBatChargeFaults : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceActiveBatChargeFaults()
        : SubscribeAttribute("active-bat-charge-faults")
    {
    }

    ~SubscribeAttributePowerSourceActiveBatChargeFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000001E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveBatChargeFaultsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.ActiveBatChargeFaults response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadPowerSourceGeneratedCommandList : public ReadAttribute {
public:
    ReadPowerSourceGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadPowerSourceGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributePowerSourceGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadPowerSourceAcceptedCommandList : public ReadAttribute {
public:
    ReadPowerSourceAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadPowerSourceAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributePowerSourceAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadPowerSourceAttributeList : public ReadAttribute {
public:
    ReadPowerSourceAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadPowerSourceAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributePowerSourceAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadPowerSourceFeatureMap : public ReadAttribute {
public:
    ReadPowerSourceFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadPowerSourceFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributePowerSourceFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadPowerSourceClusterRevision : public ReadAttribute {
public:
    ReadPowerSourceClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadPowerSourceClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributePowerSourceClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster GeneralCommissioning                                        | 0x0030 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ArmFailSafe                                                       |   0x00 |
| * SetRegulatoryConfig                                               |   0x02 |
| * CommissioningComplete                                             |   0x04 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Breadcrumb                                                        | 0x0000 |
| * BasicCommissioningInfo                                            | 0x0001 |
| * RegulatoryConfig                                                  | 0x0002 |
| * LocationCapability                                                | 0x0003 |
| * SupportsConcurrentConnection                                      | 0x0004 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ArmFailSafe
 */
class GeneralCommissioningArmFailSafe : public ClusterCommand {
public:
    GeneralCommissioningArmFailSafe()
        : ClusterCommand("arm-fail-safe")
    {
        AddArgument("ExpiryLengthSeconds", 0, UINT16_MAX, &mRequest.expiryLengthSeconds);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRGeneralCommissioningClusterArmFailSafeParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.expiryLengthSeconds = [NSNumber numberWithUnsignedShort:mRequest.expiryLengthSeconds];
        params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster armFailSafeWithParams:params
                                completion:^(MTRGeneralCommissioningClusterArmFailSafeResponseParams * _Nullable values,
                                    NSError * _Nullable error) {
                                    NSLog(@"Values: %@", values);
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafe::Type mRequest;
};

/*
 * Command SetRegulatoryConfig
 */
class GeneralCommissioningSetRegulatoryConfig : public ClusterCommand {
public:
    GeneralCommissioningSetRegulatoryConfig()
        : ClusterCommand("set-regulatory-config")
    {
        AddArgument("NewRegulatoryConfig", 0, UINT8_MAX, &mRequest.newRegulatoryConfig);
        AddArgument("CountryCode", &mRequest.countryCode);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRGeneralCommissioningClusterSetRegulatoryConfigParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.newRegulatoryConfig = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.newRegulatoryConfig)];
        params.countryCode = [[NSString alloc] initWithBytes:mRequest.countryCode.data()
                                                      length:mRequest.countryCode.size()
                                                    encoding:NSUTF8StringEncoding];
        params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                setRegulatoryConfigWithParams:params
                                   completion:^(MTRGeneralCommissioningClusterSetRegulatoryConfigResponseParams * _Nullable values,
                                       NSError * _Nullable error) {
                                       NSLog(@"Values: %@", values);
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfig::Type mRequest;
};

/*
 * Command CommissioningComplete
 */
class GeneralCommissioningCommissioningComplete : public ClusterCommand {
public:
    GeneralCommissioningCommissioningComplete()
        : ClusterCommand("commissioning-complete")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRGeneralCommissioningClusterCommissioningCompleteParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster commissioningCompleteWithParams:params
                                          completion:^(
                                              MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable values,
                                              NSError * _Nullable error) {
                                              NSLog(@"Values: %@", values);
                                              responsesNeeded--;
                                              if (error != nil) {
                                                  mError = error;
                                                  LogNSError("Error", error);
                                              }
                                              if (responsesNeeded == 0) {
                                                  SetCommandExitStatus(mError);
                                              }
                                          }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Breadcrumb
 */
class ReadGeneralCommissioningBreadcrumb : public ReadAttribute {
public:
    ReadGeneralCommissioningBreadcrumb()
        : ReadAttribute("breadcrumb")
    {
    }

    ~ReadGeneralCommissioningBreadcrumb() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeBreadcrumbWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.Breadcrumb response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning Breadcrumb read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteGeneralCommissioningBreadcrumb : public WriteAttribute {
public:
    WriteGeneralCommissioningBreadcrumb()
        : WriteAttribute("breadcrumb")
    {
        AddArgument("attr-name", "breadcrumb");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteGeneralCommissioningBreadcrumb() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeBreadcrumbWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("GeneralCommissioning Breadcrumb write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeGeneralCommissioningBreadcrumb : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningBreadcrumb()
        : SubscribeAttribute("breadcrumb")
    {
    }

    ~SubscribeAttributeGeneralCommissioningBreadcrumb() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBreadcrumbWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.Breadcrumb response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BasicCommissioningInfo
 */
class ReadGeneralCommissioningBasicCommissioningInfo : public ReadAttribute {
public:
    ReadGeneralCommissioningBasicCommissioningInfo()
        : ReadAttribute("basic-commissioning-info")
    {
    }

    ~ReadGeneralCommissioningBasicCommissioningInfo() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeBasicCommissioningInfoWithCompletion:^(
            MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.BasicCommissioningInfo response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning BasicCommissioningInfo read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningBasicCommissioningInfo : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningBasicCommissioningInfo()
        : SubscribeAttribute("basic-commissioning-info")
    {
    }

    ~SubscribeAttributeGeneralCommissioningBasicCommissioningInfo() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBasicCommissioningInfoWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.BasicCommissioningInfo response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RegulatoryConfig
 */
class ReadGeneralCommissioningRegulatoryConfig : public ReadAttribute {
public:
    ReadGeneralCommissioningRegulatoryConfig()
        : ReadAttribute("regulatory-config")
    {
    }

    ~ReadGeneralCommissioningRegulatoryConfig() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeRegulatoryConfigWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.RegulatoryConfig response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning RegulatoryConfig read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningRegulatoryConfig : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningRegulatoryConfig()
        : SubscribeAttribute("regulatory-config")
    {
    }

    ~SubscribeAttributeGeneralCommissioningRegulatoryConfig() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRegulatoryConfigWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.RegulatoryConfig response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LocationCapability
 */
class ReadGeneralCommissioningLocationCapability : public ReadAttribute {
public:
    ReadGeneralCommissioningLocationCapability()
        : ReadAttribute("location-capability")
    {
    }

    ~ReadGeneralCommissioningLocationCapability() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLocationCapabilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.LocationCapability response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning LocationCapability read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningLocationCapability : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningLocationCapability()
        : SubscribeAttribute("location-capability")
    {
    }

    ~SubscribeAttributeGeneralCommissioningLocationCapability() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLocationCapabilityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.LocationCapability response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SupportsConcurrentConnection
 */
class ReadGeneralCommissioningSupportsConcurrentConnection : public ReadAttribute {
public:
    ReadGeneralCommissioningSupportsConcurrentConnection()
        : ReadAttribute("supports-concurrent-connection")
    {
    }

    ~ReadGeneralCommissioningSupportsConcurrentConnection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeSupportsConcurrentConnectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.SupportsConcurrentConnection response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning SupportsConcurrentConnection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningSupportsConcurrentConnection : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningSupportsConcurrentConnection()
        : SubscribeAttribute("supports-concurrent-connection")
    {
    }

    ~SubscribeAttributeGeneralCommissioningSupportsConcurrentConnection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSupportsConcurrentConnectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.SupportsConcurrentConnection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadGeneralCommissioningGeneratedCommandList : public ReadAttribute {
public:
    ReadGeneralCommissioningGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadGeneralCommissioningGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeGeneralCommissioningGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadGeneralCommissioningAcceptedCommandList : public ReadAttribute {
public:
    ReadGeneralCommissioningAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadGeneralCommissioningAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeGeneralCommissioningAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadGeneralCommissioningAttributeList : public ReadAttribute {
public:
    ReadGeneralCommissioningAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadGeneralCommissioningAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeGeneralCommissioningAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadGeneralCommissioningFeatureMap : public ReadAttribute {
public:
    ReadGeneralCommissioningFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadGeneralCommissioningFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeGeneralCommissioningFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadGeneralCommissioningClusterRevision : public ReadAttribute {
public:
    ReadGeneralCommissioningClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadGeneralCommissioningClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeGeneralCommissioningClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster NetworkCommissioning                                        | 0x0031 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ScanNetworks                                                      |   0x00 |
| * AddOrUpdateWiFiNetwork                                            |   0x02 |
| * AddOrUpdateThreadNetwork                                          |   0x03 |
| * RemoveNetwork                                                     |   0x04 |
| * ConnectNetwork                                                    |   0x06 |
| * ReorderNetwork                                                    |   0x08 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MaxNetworks                                                       | 0x0000 |
| * Networks                                                          | 0x0001 |
| * ScanMaxTimeSeconds                                                | 0x0002 |
| * ConnectMaxTimeSeconds                                             | 0x0003 |
| * InterfaceEnabled                                                  | 0x0004 |
| * LastNetworkingStatus                                              | 0x0005 |
| * LastNetworkID                                                     | 0x0006 |
| * LastConnectErrorValue                                             | 0x0007 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ScanNetworks
 */
class NetworkCommissioningScanNetworks : public ClusterCommand {
public:
    NetworkCommissioningScanNetworks()
        : ClusterCommand("scan-networks")
    {
        AddArgument("Ssid", &mRequest.ssid);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRNetworkCommissioningClusterScanNetworksParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.ssid.HasValue()) {
            if (mRequest.ssid.Value().IsNull()) {
                params.ssid = nil;
            } else {
                params.ssid = [NSData dataWithBytes:mRequest.ssid.Value().Value().data()
                                             length:mRequest.ssid.Value().Value().size()];
            }
        } else {
            params.ssid = nil;
        }
        if (mRequest.breadcrumb.HasValue()) {
            params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb.Value()];
        } else {
            params.breadcrumb = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster scanNetworksWithParams:params
                                 completion:^(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable values,
                                     NSError * _Nullable error) {
                                     NSLog(@"Values: %@", values);
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworks::Type mRequest;
};

/*
 * Command AddOrUpdateWiFiNetwork
 */
class NetworkCommissioningAddOrUpdateWiFiNetwork : public ClusterCommand {
public:
    NetworkCommissioningAddOrUpdateWiFiNetwork()
        : ClusterCommand("add-or-update-wi-fi-network")
    {
        AddArgument("Ssid", &mRequest.ssid);
        AddArgument("Credentials", &mRequest.credentials);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRNetworkCommissioningClusterAddOrUpdateWiFiNetworkParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.ssid = [NSData dataWithBytes:mRequest.ssid.data() length:mRequest.ssid.size()];
        params.credentials = [NSData dataWithBytes:mRequest.credentials.data() length:mRequest.credentials.size()];
        if (mRequest.breadcrumb.HasValue()) {
            params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb.Value()];
        } else {
            params.breadcrumb = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                addOrUpdateWiFiNetworkWithParams:params
                                      completion:^(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable values,
                                          NSError * _Nullable error) {
                                          NSLog(@"Values: %@", values);
                                          responsesNeeded--;
                                          if (error != nil) {
                                              mError = error;
                                              LogNSError("Error", error);
                                          }
                                          if (responsesNeeded == 0) {
                                              SetCommandExitStatus(mError);
                                          }
                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::NetworkCommissioning::Commands::AddOrUpdateWiFiNetwork::Type mRequest;
};

/*
 * Command AddOrUpdateThreadNetwork
 */
class NetworkCommissioningAddOrUpdateThreadNetwork : public ClusterCommand {
public:
    NetworkCommissioningAddOrUpdateThreadNetwork()
        : ClusterCommand("add-or-update-thread-network")
    {
        AddArgument("OperationalDataset", &mRequest.operationalDataset);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRNetworkCommissioningClusterAddOrUpdateThreadNetworkParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.operationalDataset = [NSData dataWithBytes:mRequest.operationalDataset.data()
                                                   length:mRequest.operationalDataset.size()];
        if (mRequest.breadcrumb.HasValue()) {
            params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb.Value()];
        } else {
            params.breadcrumb = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                addOrUpdateThreadNetworkWithParams:params
                                        completion:^(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable values,
                                            NSError * _Nullable error) {
                                            NSLog(@"Values: %@", values);
                                            responsesNeeded--;
                                            if (error != nil) {
                                                mError = error;
                                                LogNSError("Error", error);
                                            }
                                            if (responsesNeeded == 0) {
                                                SetCommandExitStatus(mError);
                                            }
                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::NetworkCommissioning::Commands::AddOrUpdateThreadNetwork::Type mRequest;
};

/*
 * Command RemoveNetwork
 */
class NetworkCommissioningRemoveNetwork : public ClusterCommand {
public:
    NetworkCommissioningRemoveNetwork()
        : ClusterCommand("remove-network")
    {
        AddArgument("NetworkID", &mRequest.networkID);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRNetworkCommissioningClusterRemoveNetworkParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.networkID = [NSData dataWithBytes:mRequest.networkID.data() length:mRequest.networkID.size()];
        if (mRequest.breadcrumb.HasValue()) {
            params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb.Value()];
        } else {
            params.breadcrumb = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster removeNetworkWithParams:params
                                  completion:^(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable values,
                                      NSError * _Nullable error) {
                                      NSLog(@"Values: %@", values);
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::NetworkCommissioning::Commands::RemoveNetwork::Type mRequest;
};

/*
 * Command ConnectNetwork
 */
class NetworkCommissioningConnectNetwork : public ClusterCommand {
public:
    NetworkCommissioningConnectNetwork()
        : ClusterCommand("connect-network")
    {
        AddArgument("NetworkID", &mRequest.networkID);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRNetworkCommissioningClusterConnectNetworkParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.networkID = [NSData dataWithBytes:mRequest.networkID.data() length:mRequest.networkID.size()];
        if (mRequest.breadcrumb.HasValue()) {
            params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb.Value()];
        } else {
            params.breadcrumb = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster connectNetworkWithParams:params
                                   completion:^(MTRNetworkCommissioningClusterConnectNetworkResponseParams * _Nullable values,
                                       NSError * _Nullable error) {
                                       NSLog(@"Values: %@", values);
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetwork::Type mRequest;
};

/*
 * Command ReorderNetwork
 */
class NetworkCommissioningReorderNetwork : public ClusterCommand {
public:
    NetworkCommissioningReorderNetwork()
        : ClusterCommand("reorder-network")
    {
        AddArgument("NetworkID", &mRequest.networkID);
        AddArgument("NetworkIndex", 0, UINT8_MAX, &mRequest.networkIndex);
        AddArgument("Breadcrumb", 0, UINT64_MAX, &mRequest.breadcrumb);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) command (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRNetworkCommissioningClusterReorderNetworkParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.networkID = [NSData dataWithBytes:mRequest.networkID.data() length:mRequest.networkID.size()];
        params.networkIndex = [NSNumber numberWithUnsignedChar:mRequest.networkIndex];
        if (mRequest.breadcrumb.HasValue()) {
            params.breadcrumb = [NSNumber numberWithUnsignedLongLong:mRequest.breadcrumb.Value()];
        } else {
            params.breadcrumb = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster reorderNetworkWithParams:params
                                   completion:^(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable values,
                                       NSError * _Nullable error) {
                                       NSLog(@"Values: %@", values);
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::NetworkCommissioning::Commands::ReorderNetwork::Type mRequest;
};

/*
 * Attribute MaxNetworks
 */
class ReadNetworkCommissioningMaxNetworks : public ReadAttribute {
public:
    ReadNetworkCommissioningMaxNetworks()
        : ReadAttribute("max-networks")
    {
    }

    ~ReadNetworkCommissioningMaxNetworks() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeMaxNetworksWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.MaxNetworks response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning MaxNetworks read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningMaxNetworks : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningMaxNetworks()
        : SubscribeAttribute("max-networks")
    {
    }

    ~SubscribeAttributeNetworkCommissioningMaxNetworks() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxNetworksWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.MaxNetworks response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Networks
 */
class ReadNetworkCommissioningNetworks : public ReadAttribute {
public:
    ReadNetworkCommissioningNetworks()
        : ReadAttribute("networks")
    {
    }

    ~ReadNetworkCommissioningNetworks() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeNetworksWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.Networks response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning Networks read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningNetworks : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningNetworks()
        : SubscribeAttribute("networks")
    {
    }

    ~SubscribeAttributeNetworkCommissioningNetworks() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNetworksWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.Networks response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ScanMaxTimeSeconds
 */
class ReadNetworkCommissioningScanMaxTimeSeconds : public ReadAttribute {
public:
    ReadNetworkCommissioningScanMaxTimeSeconds()
        : ReadAttribute("scan-max-time-seconds")
    {
    }

    ~ReadNetworkCommissioningScanMaxTimeSeconds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeScanMaxTimeSecondsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.ScanMaxTimeSeconds response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning ScanMaxTimeSeconds read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningScanMaxTimeSeconds : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningScanMaxTimeSeconds()
        : SubscribeAttribute("scan-max-time-seconds")
    {
    }

    ~SubscribeAttributeNetworkCommissioningScanMaxTimeSeconds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeScanMaxTimeSecondsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.ScanMaxTimeSeconds response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ConnectMaxTimeSeconds
 */
class ReadNetworkCommissioningConnectMaxTimeSeconds : public ReadAttribute {
public:
    ReadNetworkCommissioningConnectMaxTimeSeconds()
        : ReadAttribute("connect-max-time-seconds")
    {
    }

    ~ReadNetworkCommissioningConnectMaxTimeSeconds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeConnectMaxTimeSecondsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.ConnectMaxTimeSeconds response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning ConnectMaxTimeSeconds read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningConnectMaxTimeSeconds : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningConnectMaxTimeSeconds()
        : SubscribeAttribute("connect-max-time-seconds")
    {
    }

    ~SubscribeAttributeNetworkCommissioningConnectMaxTimeSeconds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConnectMaxTimeSecondsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.ConnectMaxTimeSeconds response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InterfaceEnabled
 */
class ReadNetworkCommissioningInterfaceEnabled : public ReadAttribute {
public:
    ReadNetworkCommissioningInterfaceEnabled()
        : ReadAttribute("interface-enabled")
    {
    }

    ~ReadNetworkCommissioningInterfaceEnabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeInterfaceEnabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.InterfaceEnabled response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning InterfaceEnabled read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteNetworkCommissioningInterfaceEnabled : public WriteAttribute {
public:
    WriteNetworkCommissioningInterfaceEnabled()
        : WriteAttribute("interface-enabled")
    {
        AddArgument("attr-name", "interface-enabled");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteNetworkCommissioningInterfaceEnabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) WriteAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeInterfaceEnabledWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("NetworkCommissioning InterfaceEnabled write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeNetworkCommissioningInterfaceEnabled : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningInterfaceEnabled()
        : SubscribeAttribute("interface-enabled")
    {
    }

    ~SubscribeAttributeNetworkCommissioningInterfaceEnabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInterfaceEnabledWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.InterfaceEnabled response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LastNetworkingStatus
 */
class ReadNetworkCommissioningLastNetworkingStatus : public ReadAttribute {
public:
    ReadNetworkCommissioningLastNetworkingStatus()
        : ReadAttribute("last-networking-status")
    {
    }

    ~ReadNetworkCommissioningLastNetworkingStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLastNetworkingStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.LastNetworkingStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning LastNetworkingStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningLastNetworkingStatus : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningLastNetworkingStatus()
        : SubscribeAttribute("last-networking-status")
    {
    }

    ~SubscribeAttributeNetworkCommissioningLastNetworkingStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLastNetworkingStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.LastNetworkingStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LastNetworkID
 */
class ReadNetworkCommissioningLastNetworkID : public ReadAttribute {
public:
    ReadNetworkCommissioningLastNetworkID()
        : ReadAttribute("last-network-id")
    {
    }

    ~ReadNetworkCommissioningLastNetworkID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLastNetworkIDWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.LastNetworkID response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning LastNetworkID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningLastNetworkID : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningLastNetworkID()
        : SubscribeAttribute("last-network-id")
    {
    }

    ~SubscribeAttributeNetworkCommissioningLastNetworkID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLastNetworkIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.LastNetworkID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LastConnectErrorValue
 */
class ReadNetworkCommissioningLastConnectErrorValue : public ReadAttribute {
public:
    ReadNetworkCommissioningLastConnectErrorValue()
        : ReadAttribute("last-connect-error-value")
    {
    }

    ~ReadNetworkCommissioningLastConnectErrorValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLastConnectErrorValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.LastConnectErrorValue response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning LastConnectErrorValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningLastConnectErrorValue : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningLastConnectErrorValue()
        : SubscribeAttribute("last-connect-error-value")
    {
    }

    ~SubscribeAttributeNetworkCommissioningLastConnectErrorValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLastConnectErrorValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.LastConnectErrorValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadNetworkCommissioningGeneratedCommandList : public ReadAttribute {
public:
    ReadNetworkCommissioningGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadNetworkCommissioningGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeNetworkCommissioningGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadNetworkCommissioningAcceptedCommandList : public ReadAttribute {
public:
    ReadNetworkCommissioningAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadNetworkCommissioningAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeNetworkCommissioningAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadNetworkCommissioningAttributeList : public ReadAttribute {
public:
    ReadNetworkCommissioningAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadNetworkCommissioningAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeNetworkCommissioningAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadNetworkCommissioningFeatureMap : public ReadAttribute {
public:
    ReadNetworkCommissioningFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadNetworkCommissioningFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeNetworkCommissioningFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadNetworkCommissioningClusterRevision : public ReadAttribute {
public:
    ReadNetworkCommissioningClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadNetworkCommissioningClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeNetworkCommissioningClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster DiagnosticLogs                                              | 0x0032 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * RetrieveLogsRequest                                               |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command RetrieveLogsRequest
 */
class DiagnosticLogsRetrieveLogsRequest : public ClusterCommand {
public:
    DiagnosticLogsRetrieveLogsRequest()
        : ClusterCommand("retrieve-logs-request")
    {
        AddArgument("Intent", 0, UINT8_MAX, &mRequest.intent);
        AddArgument("RequestedProtocol", 0, UINT8_MAX, &mRequest.requestedProtocol);
        AddArgument("TransferFileDesignator", &mRequest.transferFileDesignator);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRDiagnosticLogsClusterRetrieveLogsRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.intent = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.intent)];
        params.requestedProtocol = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.requestedProtocol)];
        if (mRequest.transferFileDesignator.HasValue()) {
            params.transferFileDesignator = [[NSString alloc] initWithBytes:mRequest.transferFileDesignator.Value().data()
                                                                     length:mRequest.transferFileDesignator.Value().size()
                                                                   encoding:NSUTF8StringEncoding];
        } else {
            params.transferFileDesignator = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster retrieveLogsRequestWithParams:params
                                        completion:^(MTRDiagnosticLogsClusterRetrieveLogsResponseParams * _Nullable values,
                                            NSError * _Nullable error) {
                                            NSLog(@"Values: %@", values);
                                            responsesNeeded--;
                                            if (error != nil) {
                                                mError = error;
                                                LogNSError("Error", error);
                                            }
                                            if (responsesNeeded == 0) {
                                                SetCommandExitStatus(mError);
                                            }
                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DiagnosticLogs::Commands::RetrieveLogsRequest::Type mRequest;
};

/*
 * Attribute GeneratedCommandList
 */
class ReadDiagnosticLogsGeneratedCommandList : public ReadAttribute {
public:
    ReadDiagnosticLogsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadDiagnosticLogsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DiagnosticLogs.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("DiagnosticLogs GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDiagnosticLogsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeDiagnosticLogsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeDiagnosticLogsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DiagnosticLogs.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadDiagnosticLogsAcceptedCommandList : public ReadAttribute {
public:
    ReadDiagnosticLogsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadDiagnosticLogsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DiagnosticLogs.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("DiagnosticLogs AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDiagnosticLogsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeDiagnosticLogsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeDiagnosticLogsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DiagnosticLogs.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadDiagnosticLogsAttributeList : public ReadAttribute {
public:
    ReadDiagnosticLogsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadDiagnosticLogsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DiagnosticLogs.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("DiagnosticLogs AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDiagnosticLogsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeDiagnosticLogsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeDiagnosticLogsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DiagnosticLogs.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadDiagnosticLogsFeatureMap : public ReadAttribute {
public:
    ReadDiagnosticLogsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadDiagnosticLogsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DiagnosticLogs.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("DiagnosticLogs FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDiagnosticLogsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeDiagnosticLogsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeDiagnosticLogsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DiagnosticLogs.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadDiagnosticLogsClusterRevision : public ReadAttribute {
public:
    ReadDiagnosticLogsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadDiagnosticLogsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DiagnosticLogs.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("DiagnosticLogs ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDiagnosticLogsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeDiagnosticLogsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeDiagnosticLogsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DiagnosticLogs.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster GeneralDiagnostics                                          | 0x0033 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * TestEventTrigger                                                  |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * NetworkInterfaces                                                 | 0x0000 |
| * RebootCount                                                       | 0x0001 |
| * UpTime                                                            | 0x0002 |
| * TotalOperationalHours                                             | 0x0003 |
| * BootReason                                                        | 0x0004 |
| * ActiveHardwareFaults                                              | 0x0005 |
| * ActiveRadioFaults                                                 | 0x0006 |
| * ActiveNetworkFaults                                               | 0x0007 |
| * TestEventTriggersEnabled                                          | 0x0008 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * HardwareFaultChange                                               | 0x0000 |
| * RadioFaultChange                                                  | 0x0001 |
| * NetworkFaultChange                                                | 0x0002 |
| * BootReason                                                        | 0x0003 |
\*----------------------------------------------------------------------------*/

/*
 * Command TestEventTrigger
 */
class GeneralDiagnosticsTestEventTrigger : public ClusterCommand {
public:
    GeneralDiagnosticsTestEventTrigger()
        : ClusterCommand("test-event-trigger")
    {
        AddArgument("EnableKey", &mRequest.enableKey);
        AddArgument("EventTrigger", 0, UINT64_MAX, &mRequest.eventTrigger);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRGeneralDiagnosticsClusterTestEventTriggerParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.enableKey = [NSData dataWithBytes:mRequest.enableKey.data() length:mRequest.enableKey.size()];
        params.eventTrigger = [NSNumber numberWithUnsignedLongLong:mRequest.eventTrigger];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testEventTriggerWithParams:params
                                     completion:^(NSError * _Nullable error) {
                                         responsesNeeded--;
                                         if (error != nil) {
                                             mError = error;
                                             LogNSError("Error", error);
                                         }
                                         if (responsesNeeded == 0) {
                                             SetCommandExitStatus(mError);
                                         }
                                     }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::GeneralDiagnostics::Commands::TestEventTrigger::Type mRequest;
};

/*
 * Attribute NetworkInterfaces
 */
class ReadGeneralDiagnosticsNetworkInterfaces : public ReadAttribute {
public:
    ReadGeneralDiagnosticsNetworkInterfaces()
        : ReadAttribute("network-interfaces")
    {
    }

    ~ReadGeneralDiagnosticsNetworkInterfaces() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeNetworkInterfacesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.NetworkInterfaces response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics NetworkInterfaces read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsNetworkInterfaces : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsNetworkInterfaces()
        : SubscribeAttribute("network-interfaces")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsNetworkInterfaces() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNetworkInterfacesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.NetworkInterfaces response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RebootCount
 */
class ReadGeneralDiagnosticsRebootCount : public ReadAttribute {
public:
    ReadGeneralDiagnosticsRebootCount()
        : ReadAttribute("reboot-count")
    {
    }

    ~ReadGeneralDiagnosticsRebootCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeRebootCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.RebootCount response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics RebootCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsRebootCount : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsRebootCount()
        : SubscribeAttribute("reboot-count")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsRebootCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRebootCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.RebootCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UpTime
 */
class ReadGeneralDiagnosticsUpTime : public ReadAttribute {
public:
    ReadGeneralDiagnosticsUpTime()
        : ReadAttribute("up-time")
    {
    }

    ~ReadGeneralDiagnosticsUpTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeUpTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.UpTime response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics UpTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsUpTime : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsUpTime()
        : SubscribeAttribute("up-time")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsUpTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUpTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.UpTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TotalOperationalHours
 */
class ReadGeneralDiagnosticsTotalOperationalHours : public ReadAttribute {
public:
    ReadGeneralDiagnosticsTotalOperationalHours()
        : ReadAttribute("total-operational-hours")
    {
    }

    ~ReadGeneralDiagnosticsTotalOperationalHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeTotalOperationalHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.TotalOperationalHours response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics TotalOperationalHours read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsTotalOperationalHours : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsTotalOperationalHours()
        : SubscribeAttribute("total-operational-hours")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsTotalOperationalHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTotalOperationalHoursWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.TotalOperationalHours response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BootReason
 */
class ReadGeneralDiagnosticsBootReason : public ReadAttribute {
public:
    ReadGeneralDiagnosticsBootReason()
        : ReadAttribute("boot-reason")
    {
    }

    ~ReadGeneralDiagnosticsBootReason() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeBootReasonWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.BootReason response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics BootReason read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsBootReason : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsBootReason()
        : SubscribeAttribute("boot-reason")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsBootReason() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBootReasonWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.BootReason response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveHardwareFaults
 */
class ReadGeneralDiagnosticsActiveHardwareFaults : public ReadAttribute {
public:
    ReadGeneralDiagnosticsActiveHardwareFaults()
        : ReadAttribute("active-hardware-faults")
    {
    }

    ~ReadGeneralDiagnosticsActiveHardwareFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeActiveHardwareFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.ActiveHardwareFaults response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics ActiveHardwareFaults read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsActiveHardwareFaults : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsActiveHardwareFaults()
        : SubscribeAttribute("active-hardware-faults")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsActiveHardwareFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveHardwareFaultsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.ActiveHardwareFaults response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveRadioFaults
 */
class ReadGeneralDiagnosticsActiveRadioFaults : public ReadAttribute {
public:
    ReadGeneralDiagnosticsActiveRadioFaults()
        : ReadAttribute("active-radio-faults")
    {
    }

    ~ReadGeneralDiagnosticsActiveRadioFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeActiveRadioFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.ActiveRadioFaults response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics ActiveRadioFaults read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsActiveRadioFaults : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsActiveRadioFaults()
        : SubscribeAttribute("active-radio-faults")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsActiveRadioFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveRadioFaultsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.ActiveRadioFaults response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveNetworkFaults
 */
class ReadGeneralDiagnosticsActiveNetworkFaults : public ReadAttribute {
public:
    ReadGeneralDiagnosticsActiveNetworkFaults()
        : ReadAttribute("active-network-faults")
    {
    }

    ~ReadGeneralDiagnosticsActiveNetworkFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeActiveNetworkFaultsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.ActiveNetworkFaults response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics ActiveNetworkFaults read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsActiveNetworkFaults : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsActiveNetworkFaults()
        : SubscribeAttribute("active-network-faults")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsActiveNetworkFaults() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveNetworkFaultsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.ActiveNetworkFaults response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TestEventTriggersEnabled
 */
class ReadGeneralDiagnosticsTestEventTriggersEnabled : public ReadAttribute {
public:
    ReadGeneralDiagnosticsTestEventTriggersEnabled()
        : ReadAttribute("test-event-triggers-enabled")
    {
    }

    ~ReadGeneralDiagnosticsTestEventTriggersEnabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeTestEventTriggersEnabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.TestEventTriggersEnabled response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics TestEventTriggersEnabled read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsTestEventTriggersEnabled : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsTestEventTriggersEnabled()
        : SubscribeAttribute("test-event-triggers-enabled")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsTestEventTriggersEnabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTestEventTriggersEnabledWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.TestEventTriggersEnabled response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadGeneralDiagnosticsGeneratedCommandList : public ReadAttribute {
public:
    ReadGeneralDiagnosticsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadGeneralDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadGeneralDiagnosticsAcceptedCommandList : public ReadAttribute {
public:
    ReadGeneralDiagnosticsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadGeneralDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadGeneralDiagnosticsAttributeList : public ReadAttribute {
public:
    ReadGeneralDiagnosticsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadGeneralDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadGeneralDiagnosticsFeatureMap : public ReadAttribute {
public:
    ReadGeneralDiagnosticsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadGeneralDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadGeneralDiagnosticsClusterRevision : public ReadAttribute {
public:
    ReadGeneralDiagnosticsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadGeneralDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster SoftwareDiagnostics                                         | 0x0034 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetWatermarks                                                   |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * ThreadMetrics                                                     | 0x0000 |
| * CurrentHeapFree                                                   | 0x0001 |
| * CurrentHeapUsed                                                   | 0x0002 |
| * CurrentHeapHighWatermark                                          | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * SoftwareFault                                                     | 0x0000 |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetWatermarks
 */
class SoftwareDiagnosticsResetWatermarks : public ClusterCommand {
public:
    SoftwareDiagnosticsResetWatermarks()
        : ClusterCommand("reset-watermarks")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSoftwareDiagnosticsClusterResetWatermarksParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetWatermarksWithParams:params
                                    completion:^(NSError * _Nullable error) {
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute ThreadMetrics
 */
class ReadSoftwareDiagnosticsThreadMetrics : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsThreadMetrics()
        : ReadAttribute("thread-metrics")
    {
    }

    ~ReadSoftwareDiagnosticsThreadMetrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeThreadMetricsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.ThreadMetrics response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics ThreadMetrics read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsThreadMetrics : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsThreadMetrics()
        : SubscribeAttribute("thread-metrics")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsThreadMetrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeThreadMetricsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.ThreadMetrics response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentHeapFree
 */
class ReadSoftwareDiagnosticsCurrentHeapFree : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsCurrentHeapFree()
        : ReadAttribute("current-heap-free")
    {
    }

    ~ReadSoftwareDiagnosticsCurrentHeapFree() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeCurrentHeapFreeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.CurrentHeapFree response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics CurrentHeapFree read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsCurrentHeapFree : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsCurrentHeapFree()
        : SubscribeAttribute("current-heap-free")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsCurrentHeapFree() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentHeapFreeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.CurrentHeapFree response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentHeapUsed
 */
class ReadSoftwareDiagnosticsCurrentHeapUsed : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsCurrentHeapUsed()
        : ReadAttribute("current-heap-used")
    {
    }

    ~ReadSoftwareDiagnosticsCurrentHeapUsed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeCurrentHeapUsedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.CurrentHeapUsed response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics CurrentHeapUsed read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsCurrentHeapUsed : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsCurrentHeapUsed()
        : SubscribeAttribute("current-heap-used")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsCurrentHeapUsed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentHeapUsedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.CurrentHeapUsed response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentHeapHighWatermark
 */
class ReadSoftwareDiagnosticsCurrentHeapHighWatermark : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsCurrentHeapHighWatermark()
        : ReadAttribute("current-heap-high-watermark")
    {
    }

    ~ReadSoftwareDiagnosticsCurrentHeapHighWatermark() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeCurrentHeapHighWatermarkWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.CurrentHeapHighWatermark response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics CurrentHeapHighWatermark read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsCurrentHeapHighWatermark : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsCurrentHeapHighWatermark()
        : SubscribeAttribute("current-heap-high-watermark")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsCurrentHeapHighWatermark() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentHeapHighWatermarkWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.CurrentHeapHighWatermark response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadSoftwareDiagnosticsGeneratedCommandList : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadSoftwareDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadSoftwareDiagnosticsAcceptedCommandList : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadSoftwareDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadSoftwareDiagnosticsAttributeList : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadSoftwareDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadSoftwareDiagnosticsFeatureMap : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadSoftwareDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadSoftwareDiagnosticsClusterRevision : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadSoftwareDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ThreadNetworkDiagnostics                                    | 0x0035 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCounts                                                       |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Channel                                                           | 0x0000 |
| * RoutingRole                                                       | 0x0001 |
| * NetworkName                                                       | 0x0002 |
| * PanId                                                             | 0x0003 |
| * ExtendedPanId                                                     | 0x0004 |
| * MeshLocalPrefix                                                   | 0x0005 |
| * OverrunCount                                                      | 0x0006 |
| * NeighborTable                                                     | 0x0007 |
| * RouteTable                                                        | 0x0008 |
| * PartitionId                                                       | 0x0009 |
| * Weighting                                                         | 0x000A |
| * DataVersion                                                       | 0x000B |
| * StableDataVersion                                                 | 0x000C |
| * LeaderRouterId                                                    | 0x000D |
| * DetachedRoleCount                                                 | 0x000E |
| * ChildRoleCount                                                    | 0x000F |
| * RouterRoleCount                                                   | 0x0010 |
| * LeaderRoleCount                                                   | 0x0011 |
| * AttachAttemptCount                                                | 0x0012 |
| * PartitionIdChangeCount                                            | 0x0013 |
| * BetterPartitionAttachAttemptCount                                 | 0x0014 |
| * ParentChangeCount                                                 | 0x0015 |
| * TxTotalCount                                                      | 0x0016 |
| * TxUnicastCount                                                    | 0x0017 |
| * TxBroadcastCount                                                  | 0x0018 |
| * TxAckRequestedCount                                               | 0x0019 |
| * TxAckedCount                                                      | 0x001A |
| * TxNoAckRequestedCount                                             | 0x001B |
| * TxDataCount                                                       | 0x001C |
| * TxDataPollCount                                                   | 0x001D |
| * TxBeaconCount                                                     | 0x001E |
| * TxBeaconRequestCount                                              | 0x001F |
| * TxOtherCount                                                      | 0x0020 |
| * TxRetryCount                                                      | 0x0021 |
| * TxDirectMaxRetryExpiryCount                                       | 0x0022 |
| * TxIndirectMaxRetryExpiryCount                                     | 0x0023 |
| * TxErrCcaCount                                                     | 0x0024 |
| * TxErrAbortCount                                                   | 0x0025 |
| * TxErrBusyChannelCount                                             | 0x0026 |
| * RxTotalCount                                                      | 0x0027 |
| * RxUnicastCount                                                    | 0x0028 |
| * RxBroadcastCount                                                  | 0x0029 |
| * RxDataCount                                                       | 0x002A |
| * RxDataPollCount                                                   | 0x002B |
| * RxBeaconCount                                                     | 0x002C |
| * RxBeaconRequestCount                                              | 0x002D |
| * RxOtherCount                                                      | 0x002E |
| * RxAddressFilteredCount                                            | 0x002F |
| * RxDestAddrFilteredCount                                           | 0x0030 |
| * RxDuplicatedCount                                                 | 0x0031 |
| * RxErrNoFrameCount                                                 | 0x0032 |
| * RxErrUnknownNeighborCount                                         | 0x0033 |
| * RxErrInvalidSrcAddrCount                                          | 0x0034 |
| * RxErrSecCount                                                     | 0x0035 |
| * RxErrFcsCount                                                     | 0x0036 |
| * RxErrOtherCount                                                   | 0x0037 |
| * ActiveTimestamp                                                   | 0x0038 |
| * PendingTimestamp                                                  | 0x0039 |
| * Delay                                                             | 0x003A |
| * SecurityPolicy                                                    | 0x003B |
| * ChannelPage0Mask                                                  | 0x003C |
| * OperationalDatasetComponents                                      | 0x003D |
| * ActiveNetworkFaultsList                                           | 0x003E |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * ConnectionStatus                                                  | 0x0000 |
| * NetworkFaultChange                                                | 0x0001 |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCounts
 */
class ThreadNetworkDiagnosticsResetCounts : public ClusterCommand {
public:
    ThreadNetworkDiagnosticsResetCounts()
        : ClusterCommand("reset-counts")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRThreadNetworkDiagnosticsClusterResetCountsParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetCountsWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Channel
 */
class ReadThreadNetworkDiagnosticsChannel : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsChannel()
        : ReadAttribute("channel")
    {
    }

    ~ReadThreadNetworkDiagnosticsChannel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeChannelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.Channel response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics Channel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsChannel : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsChannel()
        : SubscribeAttribute("channel")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsChannel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChannelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.Channel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RoutingRole
 */
class ReadThreadNetworkDiagnosticsRoutingRole : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRoutingRole()
        : ReadAttribute("routing-role")
    {
    }

    ~ReadThreadNetworkDiagnosticsRoutingRole() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRoutingRoleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RoutingRole response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RoutingRole read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRoutingRole : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRoutingRole()
        : SubscribeAttribute("routing-role")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRoutingRole() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRoutingRoleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RoutingRole response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NetworkName
 */
class ReadThreadNetworkDiagnosticsNetworkName : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsNetworkName()
        : ReadAttribute("network-name")
    {
    }

    ~ReadThreadNetworkDiagnosticsNetworkName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeNetworkNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.NetworkName response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics NetworkName read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsNetworkName : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsNetworkName()
        : SubscribeAttribute("network-name")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsNetworkName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNetworkNameWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.NetworkName response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PanId
 */
class ReadThreadNetworkDiagnosticsPanId : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsPanId()
        : ReadAttribute("pan-id")
    {
    }

    ~ReadThreadNetworkDiagnosticsPanId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributePanIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.PanId response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics PanId read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsPanId : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsPanId()
        : SubscribeAttribute("pan-id")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsPanId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePanIdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.PanId response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ExtendedPanId
 */
class ReadThreadNetworkDiagnosticsExtendedPanId : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsExtendedPanId()
        : ReadAttribute("extended-pan-id")
    {
    }

    ~ReadThreadNetworkDiagnosticsExtendedPanId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeExtendedPanIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.ExtendedPanId response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics ExtendedPanId read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsExtendedPanId : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsExtendedPanId()
        : SubscribeAttribute("extended-pan-id")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsExtendedPanId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeExtendedPanIdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.ExtendedPanId response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MeshLocalPrefix
 */
class ReadThreadNetworkDiagnosticsMeshLocalPrefix : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsMeshLocalPrefix()
        : ReadAttribute("mesh-local-prefix")
    {
    }

    ~ReadThreadNetworkDiagnosticsMeshLocalPrefix() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeMeshLocalPrefixWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.MeshLocalPrefix response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics MeshLocalPrefix read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsMeshLocalPrefix : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsMeshLocalPrefix()
        : SubscribeAttribute("mesh-local-prefix")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsMeshLocalPrefix() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeshLocalPrefixWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.MeshLocalPrefix response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OverrunCount
 */
class ReadThreadNetworkDiagnosticsOverrunCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsOverrunCount()
        : ReadAttribute("overrun-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsOverrunCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeOverrunCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.OverrunCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics OverrunCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsOverrunCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsOverrunCount()
        : SubscribeAttribute("overrun-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsOverrunCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOverrunCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.OverrunCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NeighborTable
 */
class ReadThreadNetworkDiagnosticsNeighborTable : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsNeighborTable()
        : ReadAttribute("neighbor-table")
    {
    }

    ~ReadThreadNetworkDiagnosticsNeighborTable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeNeighborTableWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.NeighborTable response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics NeighborTable read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsNeighborTable : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsNeighborTable()
        : SubscribeAttribute("neighbor-table")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsNeighborTable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNeighborTableWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.NeighborTable response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RouteTable
 */
class ReadThreadNetworkDiagnosticsRouteTable : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRouteTable()
        : ReadAttribute("route-table")
    {
    }

    ~ReadThreadNetworkDiagnosticsRouteTable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRouteTableWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RouteTable response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RouteTable read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRouteTable : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRouteTable()
        : SubscribeAttribute("route-table")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRouteTable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRouteTableWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RouteTable response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PartitionId
 */
class ReadThreadNetworkDiagnosticsPartitionId : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsPartitionId()
        : ReadAttribute("partition-id")
    {
    }

    ~ReadThreadNetworkDiagnosticsPartitionId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributePartitionIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.PartitionId response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics PartitionId read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsPartitionId : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsPartitionId()
        : SubscribeAttribute("partition-id")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsPartitionId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePartitionIdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.PartitionId response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Weighting
 */
class ReadThreadNetworkDiagnosticsWeighting : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsWeighting()
        : ReadAttribute("weighting")
    {
    }

    ~ReadThreadNetworkDiagnosticsWeighting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeWeightingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.Weighting response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics Weighting read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsWeighting : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsWeighting()
        : SubscribeAttribute("weighting")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsWeighting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWeightingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.Weighting response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DataVersion
 */
class ReadThreadNetworkDiagnosticsDataVersion : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsDataVersion()
        : ReadAttribute("data-version")
    {
    }

    ~ReadThreadNetworkDiagnosticsDataVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeDataVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.DataVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics DataVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsDataVersion : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsDataVersion()
        : SubscribeAttribute("data-version")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsDataVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDataVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.DataVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StableDataVersion
 */
class ReadThreadNetworkDiagnosticsStableDataVersion : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsStableDataVersion()
        : ReadAttribute("stable-data-version")
    {
    }

    ~ReadThreadNetworkDiagnosticsStableDataVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeStableDataVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.StableDataVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics StableDataVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsStableDataVersion : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsStableDataVersion()
        : SubscribeAttribute("stable-data-version")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsStableDataVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStableDataVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.StableDataVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LeaderRouterId
 */
class ReadThreadNetworkDiagnosticsLeaderRouterId : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsLeaderRouterId()
        : ReadAttribute("leader-router-id")
    {
    }

    ~ReadThreadNetworkDiagnosticsLeaderRouterId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeLeaderRouterIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.LeaderRouterId response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics LeaderRouterId read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsLeaderRouterId : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsLeaderRouterId()
        : SubscribeAttribute("leader-router-id")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsLeaderRouterId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000000D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLeaderRouterIdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.LeaderRouterId response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DetachedRoleCount
 */
class ReadThreadNetworkDiagnosticsDetachedRoleCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsDetachedRoleCount()
        : ReadAttribute("detached-role-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsDetachedRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeDetachedRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.DetachedRoleCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics DetachedRoleCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsDetachedRoleCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsDetachedRoleCount()
        : SubscribeAttribute("detached-role-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsDetachedRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000000E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDetachedRoleCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.DetachedRoleCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChildRoleCount
 */
class ReadThreadNetworkDiagnosticsChildRoleCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsChildRoleCount()
        : ReadAttribute("child-role-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsChildRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeChildRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.ChildRoleCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics ChildRoleCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsChildRoleCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsChildRoleCount()
        : SubscribeAttribute("child-role-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsChildRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChildRoleCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.ChildRoleCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RouterRoleCount
 */
class ReadThreadNetworkDiagnosticsRouterRoleCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRouterRoleCount()
        : ReadAttribute("router-role-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRouterRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRouterRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RouterRoleCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RouterRoleCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRouterRoleCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRouterRoleCount()
        : SubscribeAttribute("router-role-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRouterRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRouterRoleCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RouterRoleCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LeaderRoleCount
 */
class ReadThreadNetworkDiagnosticsLeaderRoleCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsLeaderRoleCount()
        : ReadAttribute("leader-role-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsLeaderRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeLeaderRoleCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.LeaderRoleCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics LeaderRoleCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsLeaderRoleCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsLeaderRoleCount()
        : SubscribeAttribute("leader-role-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsLeaderRoleCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLeaderRoleCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.LeaderRoleCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttachAttemptCount
 */
class ReadThreadNetworkDiagnosticsAttachAttemptCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsAttachAttemptCount()
        : ReadAttribute("attach-attempt-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsAttachAttemptCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAttachAttemptCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.AttachAttemptCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics AttachAttemptCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsAttachAttemptCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsAttachAttemptCount()
        : SubscribeAttribute("attach-attempt-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsAttachAttemptCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttachAttemptCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.AttachAttemptCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PartitionIdChangeCount
 */
class ReadThreadNetworkDiagnosticsPartitionIdChangeCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsPartitionIdChangeCount()
        : ReadAttribute("partition-id-change-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsPartitionIdChangeCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributePartitionIdChangeCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.PartitionIdChangeCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics PartitionIdChangeCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsPartitionIdChangeCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsPartitionIdChangeCount()
        : SubscribeAttribute("partition-id-change-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsPartitionIdChangeCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePartitionIdChangeCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.PartitionIdChangeCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BetterPartitionAttachAttemptCount
 */
class ReadThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount()
        : ReadAttribute("better-partition-attach-attempt-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster
            readAttributeBetterPartitionAttachAttemptCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.BetterPartitionAttachAttemptCount response %@", [value description]);
                if (error != nil) {
                    LogNSError("ThreadNetworkDiagnostics BetterPartitionAttachAttemptCount read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount()
        : SubscribeAttribute("better-partition-attach-attempt-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBetterPartitionAttachAttemptCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.BetterPartitionAttachAttemptCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ParentChangeCount
 */
class ReadThreadNetworkDiagnosticsParentChangeCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsParentChangeCount()
        : ReadAttribute("parent-change-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsParentChangeCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeParentChangeCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.ParentChangeCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics ParentChangeCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsParentChangeCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsParentChangeCount()
        : SubscribeAttribute("parent-change-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsParentChangeCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeParentChangeCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.ParentChangeCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxTotalCount
 */
class ReadThreadNetworkDiagnosticsTxTotalCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxTotalCount()
        : ReadAttribute("tx-total-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxTotalCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxTotalCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxTotalCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxTotalCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxTotalCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxTotalCount()
        : SubscribeAttribute("tx-total-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxTotalCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxTotalCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxTotalCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxUnicastCount
 */
class ReadThreadNetworkDiagnosticsTxUnicastCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxUnicastCount()
        : ReadAttribute("tx-unicast-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxUnicastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxUnicastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxUnicastCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxUnicastCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxUnicastCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxUnicastCount()
        : SubscribeAttribute("tx-unicast-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxUnicastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxUnicastCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxUnicastCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxBroadcastCount
 */
class ReadThreadNetworkDiagnosticsTxBroadcastCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxBroadcastCount()
        : ReadAttribute("tx-broadcast-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxBroadcastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000018) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxBroadcastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxBroadcastCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxBroadcastCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxBroadcastCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxBroadcastCount()
        : SubscribeAttribute("tx-broadcast-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxBroadcastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxBroadcastCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxBroadcastCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxAckRequestedCount
 */
class ReadThreadNetworkDiagnosticsTxAckRequestedCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxAckRequestedCount()
        : ReadAttribute("tx-ack-requested-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxAckRequestedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000019) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxAckRequestedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxAckRequestedCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxAckRequestedCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxAckRequestedCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxAckRequestedCount()
        : SubscribeAttribute("tx-ack-requested-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxAckRequestedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxAckRequestedCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxAckRequestedCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxAckedCount
 */
class ReadThreadNetworkDiagnosticsTxAckedCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxAckedCount()
        : ReadAttribute("tx-acked-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxAckedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxAckedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxAckedCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxAckedCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxAckedCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxAckedCount()
        : SubscribeAttribute("tx-acked-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxAckedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxAckedCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxAckedCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxNoAckRequestedCount
 */
class ReadThreadNetworkDiagnosticsTxNoAckRequestedCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxNoAckRequestedCount()
        : ReadAttribute("tx-no-ack-requested-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxNoAckRequestedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000001B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxNoAckRequestedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxNoAckRequestedCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxNoAckRequestedCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxNoAckRequestedCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxNoAckRequestedCount()
        : SubscribeAttribute("tx-no-ack-requested-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxNoAckRequestedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxNoAckRequestedCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxNoAckRequestedCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxDataCount
 */
class ReadThreadNetworkDiagnosticsTxDataCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxDataCount()
        : ReadAttribute("tx-data-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxDataCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000001C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxDataCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxDataCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxDataCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxDataCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxDataCount()
        : SubscribeAttribute("tx-data-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxDataCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxDataCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxDataCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxDataPollCount
 */
class ReadThreadNetworkDiagnosticsTxDataPollCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxDataPollCount()
        : ReadAttribute("tx-data-poll-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxDataPollCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000001D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxDataPollCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxDataPollCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxDataPollCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxDataPollCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxDataPollCount()
        : SubscribeAttribute("tx-data-poll-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxDataPollCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000001D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxDataPollCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxDataPollCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxBeaconCount
 */
class ReadThreadNetworkDiagnosticsTxBeaconCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxBeaconCount()
        : ReadAttribute("tx-beacon-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxBeaconCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000001E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxBeaconCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxBeaconCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxBeaconCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxBeaconCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxBeaconCount()
        : SubscribeAttribute("tx-beacon-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxBeaconCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000001E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxBeaconCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxBeaconCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxBeaconRequestCount
 */
class ReadThreadNetworkDiagnosticsTxBeaconRequestCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxBeaconRequestCount()
        : ReadAttribute("tx-beacon-request-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxBeaconRequestCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000001F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxBeaconRequestCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxBeaconRequestCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxBeaconRequestCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxBeaconRequestCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxBeaconRequestCount()
        : SubscribeAttribute("tx-beacon-request-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxBeaconRequestCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000001F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxBeaconRequestCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxBeaconRequestCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxOtherCount
 */
class ReadThreadNetworkDiagnosticsTxOtherCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxOtherCount()
        : ReadAttribute("tx-other-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxOtherCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000020) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxOtherCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxOtherCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxOtherCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxOtherCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxOtherCount()
        : SubscribeAttribute("tx-other-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxOtherCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxOtherCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxOtherCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxRetryCount
 */
class ReadThreadNetworkDiagnosticsTxRetryCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxRetryCount()
        : ReadAttribute("tx-retry-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxRetryCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000021) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxRetryCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxRetryCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxRetryCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxRetryCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxRetryCount()
        : SubscribeAttribute("tx-retry-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxRetryCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxRetryCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxRetryCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxDirectMaxRetryExpiryCount
 */
class ReadThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount()
        : ReadAttribute("tx-direct-max-retry-expiry-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000022) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxDirectMaxRetryExpiryCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxDirectMaxRetryExpiryCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxDirectMaxRetryExpiryCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount()
        : SubscribeAttribute("tx-direct-max-retry-expiry-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxDirectMaxRetryExpiryCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxDirectMaxRetryExpiryCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxIndirectMaxRetryExpiryCount
 */
class ReadThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount()
        : ReadAttribute("tx-indirect-max-retry-expiry-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000023) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxIndirectMaxRetryExpiryCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxIndirectMaxRetryExpiryCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxIndirectMaxRetryExpiryCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount()
        : SubscribeAttribute("tx-indirect-max-retry-expiry-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000023) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxIndirectMaxRetryExpiryCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxIndirectMaxRetryExpiryCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxErrCcaCount
 */
class ReadThreadNetworkDiagnosticsTxErrCcaCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxErrCcaCount()
        : ReadAttribute("tx-err-cca-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxErrCcaCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000024) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxErrCcaCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxErrCcaCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxErrCcaCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxErrCcaCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxErrCcaCount()
        : SubscribeAttribute("tx-err-cca-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxErrCcaCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxErrCcaCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxErrCcaCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxErrAbortCount
 */
class ReadThreadNetworkDiagnosticsTxErrAbortCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxErrAbortCount()
        : ReadAttribute("tx-err-abort-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxErrAbortCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000025) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxErrAbortCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxErrAbortCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxErrAbortCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxErrAbortCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxErrAbortCount()
        : SubscribeAttribute("tx-err-abort-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxErrAbortCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxErrAbortCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxErrAbortCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxErrBusyChannelCount
 */
class ReadThreadNetworkDiagnosticsTxErrBusyChannelCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsTxErrBusyChannelCount()
        : ReadAttribute("tx-err-busy-channel-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsTxErrBusyChannelCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000026) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeTxErrBusyChannelCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.TxErrBusyChannelCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics TxErrBusyChannelCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsTxErrBusyChannelCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsTxErrBusyChannelCount()
        : SubscribeAttribute("tx-err-busy-channel-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsTxErrBusyChannelCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000026) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxErrBusyChannelCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.TxErrBusyChannelCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxTotalCount
 */
class ReadThreadNetworkDiagnosticsRxTotalCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxTotalCount()
        : ReadAttribute("rx-total-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxTotalCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000027) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxTotalCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxTotalCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxTotalCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxTotalCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxTotalCount()
        : SubscribeAttribute("rx-total-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxTotalCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000027) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxTotalCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxTotalCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxUnicastCount
 */
class ReadThreadNetworkDiagnosticsRxUnicastCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxUnicastCount()
        : ReadAttribute("rx-unicast-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxUnicastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000028) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxUnicastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxUnicastCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxUnicastCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxUnicastCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxUnicastCount()
        : SubscribeAttribute("rx-unicast-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxUnicastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxUnicastCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxUnicastCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxBroadcastCount
 */
class ReadThreadNetworkDiagnosticsRxBroadcastCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxBroadcastCount()
        : ReadAttribute("rx-broadcast-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxBroadcastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000029) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxBroadcastCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxBroadcastCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxBroadcastCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxBroadcastCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxBroadcastCount()
        : SubscribeAttribute("rx-broadcast-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxBroadcastCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxBroadcastCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxBroadcastCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxDataCount
 */
class ReadThreadNetworkDiagnosticsRxDataCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxDataCount()
        : ReadAttribute("rx-data-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxDataCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000002A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxDataCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxDataCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxDataCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxDataCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxDataCount()
        : SubscribeAttribute("rx-data-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxDataCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000002A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxDataCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxDataCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxDataPollCount
 */
class ReadThreadNetworkDiagnosticsRxDataPollCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxDataPollCount()
        : ReadAttribute("rx-data-poll-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxDataPollCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000002B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxDataPollCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxDataPollCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxDataPollCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxDataPollCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxDataPollCount()
        : SubscribeAttribute("rx-data-poll-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxDataPollCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000002B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxDataPollCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxDataPollCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxBeaconCount
 */
class ReadThreadNetworkDiagnosticsRxBeaconCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxBeaconCount()
        : ReadAttribute("rx-beacon-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxBeaconCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000002C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxBeaconCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxBeaconCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxBeaconCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxBeaconCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxBeaconCount()
        : SubscribeAttribute("rx-beacon-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxBeaconCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000002C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxBeaconCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxBeaconCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxBeaconRequestCount
 */
class ReadThreadNetworkDiagnosticsRxBeaconRequestCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxBeaconRequestCount()
        : ReadAttribute("rx-beacon-request-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxBeaconRequestCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000002D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxBeaconRequestCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxBeaconRequestCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxBeaconRequestCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxBeaconRequestCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxBeaconRequestCount()
        : SubscribeAttribute("rx-beacon-request-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxBeaconRequestCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000002D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxBeaconRequestCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxBeaconRequestCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxOtherCount
 */
class ReadThreadNetworkDiagnosticsRxOtherCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxOtherCount()
        : ReadAttribute("rx-other-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxOtherCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000002E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxOtherCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxOtherCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxOtherCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxOtherCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxOtherCount()
        : SubscribeAttribute("rx-other-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxOtherCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000002E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxOtherCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxOtherCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxAddressFilteredCount
 */
class ReadThreadNetworkDiagnosticsRxAddressFilteredCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxAddressFilteredCount()
        : ReadAttribute("rx-address-filtered-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxAddressFilteredCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000002F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxAddressFilteredCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxAddressFilteredCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxAddressFilteredCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxAddressFilteredCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxAddressFilteredCount()
        : SubscribeAttribute("rx-address-filtered-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxAddressFilteredCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000002F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxAddressFilteredCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxAddressFilteredCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxDestAddrFilteredCount
 */
class ReadThreadNetworkDiagnosticsRxDestAddrFilteredCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxDestAddrFilteredCount()
        : ReadAttribute("rx-dest-addr-filtered-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxDestAddrFilteredCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000030) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxDestAddrFilteredCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxDestAddrFilteredCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxDestAddrFilteredCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxDestAddrFilteredCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxDestAddrFilteredCount()
        : SubscribeAttribute("rx-dest-addr-filtered-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxDestAddrFilteredCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxDestAddrFilteredCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxDestAddrFilteredCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxDuplicatedCount
 */
class ReadThreadNetworkDiagnosticsRxDuplicatedCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxDuplicatedCount()
        : ReadAttribute("rx-duplicated-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxDuplicatedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000031) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxDuplicatedCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxDuplicatedCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxDuplicatedCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxDuplicatedCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxDuplicatedCount()
        : SubscribeAttribute("rx-duplicated-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxDuplicatedCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxDuplicatedCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxDuplicatedCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxErrNoFrameCount
 */
class ReadThreadNetworkDiagnosticsRxErrNoFrameCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxErrNoFrameCount()
        : ReadAttribute("rx-err-no-frame-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxErrNoFrameCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000032) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxErrNoFrameCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxErrNoFrameCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxErrNoFrameCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxErrNoFrameCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxErrNoFrameCount()
        : SubscribeAttribute("rx-err-no-frame-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxErrNoFrameCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxErrNoFrameCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxErrNoFrameCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxErrUnknownNeighborCount
 */
class ReadThreadNetworkDiagnosticsRxErrUnknownNeighborCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxErrUnknownNeighborCount()
        : ReadAttribute("rx-err-unknown-neighbor-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxErrUnknownNeighborCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000033) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxErrUnknownNeighborCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxErrUnknownNeighborCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxErrUnknownNeighborCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxErrUnknownNeighborCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxErrUnknownNeighborCount()
        : SubscribeAttribute("rx-err-unknown-neighbor-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxErrUnknownNeighborCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000033) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxErrUnknownNeighborCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxErrUnknownNeighborCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxErrInvalidSrcAddrCount
 */
class ReadThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount()
        : ReadAttribute("rx-err-invalid-src-addr-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000034) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxErrInvalidSrcAddrCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxErrInvalidSrcAddrCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxErrInvalidSrcAddrCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount()
        : SubscribeAttribute("rx-err-invalid-src-addr-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000034) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxErrInvalidSrcAddrCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxErrInvalidSrcAddrCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxErrSecCount
 */
class ReadThreadNetworkDiagnosticsRxErrSecCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxErrSecCount()
        : ReadAttribute("rx-err-sec-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxErrSecCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000035) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxErrSecCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxErrSecCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxErrSecCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxErrSecCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxErrSecCount()
        : SubscribeAttribute("rx-err-sec-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxErrSecCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000035) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxErrSecCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxErrSecCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxErrFcsCount
 */
class ReadThreadNetworkDiagnosticsRxErrFcsCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxErrFcsCount()
        : ReadAttribute("rx-err-fcs-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxErrFcsCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000036) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxErrFcsCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxErrFcsCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxErrFcsCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxErrFcsCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxErrFcsCount()
        : SubscribeAttribute("rx-err-fcs-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxErrFcsCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000036) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxErrFcsCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxErrFcsCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RxErrOtherCount
 */
class ReadThreadNetworkDiagnosticsRxErrOtherCount : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsRxErrOtherCount()
        : ReadAttribute("rx-err-other-count")
    {
    }

    ~ReadThreadNetworkDiagnosticsRxErrOtherCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000037) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeRxErrOtherCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.RxErrOtherCount response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics RxErrOtherCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsRxErrOtherCount : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsRxErrOtherCount()
        : SubscribeAttribute("rx-err-other-count")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsRxErrOtherCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000037) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRxErrOtherCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.RxErrOtherCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveTimestamp
 */
class ReadThreadNetworkDiagnosticsActiveTimestamp : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsActiveTimestamp()
        : ReadAttribute("active-timestamp")
    {
    }

    ~ReadThreadNetworkDiagnosticsActiveTimestamp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000038) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeActiveTimestampWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.ActiveTimestamp response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics ActiveTimestamp read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsActiveTimestamp : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsActiveTimestamp()
        : SubscribeAttribute("active-timestamp")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsActiveTimestamp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000038) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveTimestampWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.ActiveTimestamp response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PendingTimestamp
 */
class ReadThreadNetworkDiagnosticsPendingTimestamp : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsPendingTimestamp()
        : ReadAttribute("pending-timestamp")
    {
    }

    ~ReadThreadNetworkDiagnosticsPendingTimestamp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x00000039) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributePendingTimestampWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.PendingTimestamp response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics PendingTimestamp read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsPendingTimestamp : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsPendingTimestamp()
        : SubscribeAttribute("pending-timestamp")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsPendingTimestamp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x00000039) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePendingTimestampWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.PendingTimestamp response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Delay
 */
class ReadThreadNetworkDiagnosticsDelay : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsDelay()
        : ReadAttribute("delay")
    {
    }

    ~ReadThreadNetworkDiagnosticsDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000003A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.Delay response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics Delay read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsDelay : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsDelay()
        : SubscribeAttribute("delay")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000003A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDelayWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.Delay response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SecurityPolicy
 */
class ReadThreadNetworkDiagnosticsSecurityPolicy : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsSecurityPolicy()
        : ReadAttribute("security-policy")
    {
    }

    ~ReadThreadNetworkDiagnosticsSecurityPolicy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000003B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeSecurityPolicyWithCompletion:^(
            MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.SecurityPolicy response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics SecurityPolicy read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsSecurityPolicy : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsSecurityPolicy()
        : SubscribeAttribute("security-policy")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsSecurityPolicy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000003B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSecurityPolicyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.SecurityPolicy response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChannelPage0Mask
 */
class ReadThreadNetworkDiagnosticsChannelPage0Mask : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsChannelPage0Mask()
        : ReadAttribute("channel-page0mask")
    {
    }

    ~ReadThreadNetworkDiagnosticsChannelPage0Mask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000003C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeChannelPage0MaskWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.ChannelPage0Mask response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics ChannelPage0Mask read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsChannelPage0Mask : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsChannelPage0Mask()
        : SubscribeAttribute("channel-page0mask")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsChannelPage0Mask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000003C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChannelPage0MaskWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.ChannelPage0Mask response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OperationalDatasetComponents
 */
class ReadThreadNetworkDiagnosticsOperationalDatasetComponents : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsOperationalDatasetComponents()
        : ReadAttribute("operational-dataset-components")
    {
    }

    ~ReadThreadNetworkDiagnosticsOperationalDatasetComponents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000003D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeOperationalDatasetComponentsWithCompletion:^(
            MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.OperationalDatasetComponents response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics OperationalDatasetComponents read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsOperationalDatasetComponents : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsOperationalDatasetComponents()
        : SubscribeAttribute("operational-dataset-components")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsOperationalDatasetComponents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000003D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOperationalDatasetComponentsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(
                MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.OperationalDatasetComponents response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveNetworkFaultsList
 */
class ReadThreadNetworkDiagnosticsActiveNetworkFaultsList : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsActiveNetworkFaultsList()
        : ReadAttribute("active-network-faults-list")
    {
    }

    ~ReadThreadNetworkDiagnosticsActiveNetworkFaultsList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000003E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeActiveNetworkFaultsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.ActiveNetworkFaultsList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics ActiveNetworkFaultsList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsActiveNetworkFaultsList : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsActiveNetworkFaultsList()
        : SubscribeAttribute("active-network-faults-list")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsActiveNetworkFaultsList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000003E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveNetworkFaultsListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.ActiveNetworkFaultsList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadThreadNetworkDiagnosticsGeneratedCommandList : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadThreadNetworkDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadThreadNetworkDiagnosticsAcceptedCommandList : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadThreadNetworkDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadThreadNetworkDiagnosticsAttributeList : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadThreadNetworkDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadThreadNetworkDiagnosticsFeatureMap : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadThreadNetworkDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadThreadNetworkDiagnosticsClusterRevision : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadThreadNetworkDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster WiFiNetworkDiagnostics                                      | 0x0036 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCounts                                                       |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Bssid                                                             | 0x0000 |
| * SecurityType                                                      | 0x0001 |
| * WiFiVersion                                                       | 0x0002 |
| * ChannelNumber                                                     | 0x0003 |
| * Rssi                                                              | 0x0004 |
| * BeaconLostCount                                                   | 0x0005 |
| * BeaconRxCount                                                     | 0x0006 |
| * PacketMulticastRxCount                                            | 0x0007 |
| * PacketMulticastTxCount                                            | 0x0008 |
| * PacketUnicastRxCount                                              | 0x0009 |
| * PacketUnicastTxCount                                              | 0x000A |
| * CurrentMaxRate                                                    | 0x000B |
| * OverrunCount                                                      | 0x000C |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * Disconnection                                                     | 0x0000 |
| * AssociationFailure                                                | 0x0001 |
| * ConnectionStatus                                                  | 0x0002 |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCounts
 */
class WiFiNetworkDiagnosticsResetCounts : public ClusterCommand {
public:
    WiFiNetworkDiagnosticsResetCounts()
        : ClusterCommand("reset-counts")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRWiFiNetworkDiagnosticsClusterResetCountsParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetCountsWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Bssid
 */
class ReadWiFiNetworkDiagnosticsBssid : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsBssid()
        : ReadAttribute("bssid")
    {
    }

    ~ReadWiFiNetworkDiagnosticsBssid() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeBSSIDWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.BSSID response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics BSSID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsBssid : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsBssid()
        : SubscribeAttribute("bssid")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsBssid() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBSSIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.BSSID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SecurityType
 */
class ReadWiFiNetworkDiagnosticsSecurityType : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsSecurityType()
        : ReadAttribute("security-type")
    {
    }

    ~ReadWiFiNetworkDiagnosticsSecurityType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeSecurityTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.SecurityType response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics SecurityType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsSecurityType : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsSecurityType()
        : SubscribeAttribute("security-type")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsSecurityType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSecurityTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.SecurityType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WiFiVersion
 */
class ReadWiFiNetworkDiagnosticsWiFiVersion : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsWiFiVersion()
        : ReadAttribute("wi-fi-version")
    {
    }

    ~ReadWiFiNetworkDiagnosticsWiFiVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeWiFiVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.WiFiVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics WiFiVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsWiFiVersion : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsWiFiVersion()
        : SubscribeAttribute("wi-fi-version")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsWiFiVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWiFiVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.WiFiVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChannelNumber
 */
class ReadWiFiNetworkDiagnosticsChannelNumber : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsChannelNumber()
        : ReadAttribute("channel-number")
    {
    }

    ~ReadWiFiNetworkDiagnosticsChannelNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeChannelNumberWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.ChannelNumber response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics ChannelNumber read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsChannelNumber : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsChannelNumber()
        : SubscribeAttribute("channel-number")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsChannelNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChannelNumberWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.ChannelNumber response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Rssi
 */
class ReadWiFiNetworkDiagnosticsRssi : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsRssi()
        : ReadAttribute("rssi")
    {
    }

    ~ReadWiFiNetworkDiagnosticsRssi() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeRSSIWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.RSSI response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics RSSI read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsRssi : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsRssi()
        : SubscribeAttribute("rssi")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsRssi() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRSSIWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.RSSI response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BeaconLostCount
 */
class ReadWiFiNetworkDiagnosticsBeaconLostCount : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsBeaconLostCount()
        : ReadAttribute("beacon-lost-count")
    {
    }

    ~ReadWiFiNetworkDiagnosticsBeaconLostCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeBeaconLostCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.BeaconLostCount response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics BeaconLostCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsBeaconLostCount : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsBeaconLostCount()
        : SubscribeAttribute("beacon-lost-count")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsBeaconLostCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBeaconLostCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.BeaconLostCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BeaconRxCount
 */
class ReadWiFiNetworkDiagnosticsBeaconRxCount : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsBeaconRxCount()
        : ReadAttribute("beacon-rx-count")
    {
    }

    ~ReadWiFiNetworkDiagnosticsBeaconRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeBeaconRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.BeaconRxCount response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics BeaconRxCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsBeaconRxCount : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsBeaconRxCount()
        : SubscribeAttribute("beacon-rx-count")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsBeaconRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBeaconRxCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.BeaconRxCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PacketMulticastRxCount
 */
class ReadWiFiNetworkDiagnosticsPacketMulticastRxCount : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsPacketMulticastRxCount()
        : ReadAttribute("packet-multicast-rx-count")
    {
    }

    ~ReadWiFiNetworkDiagnosticsPacketMulticastRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributePacketMulticastRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.PacketMulticastRxCount response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics PacketMulticastRxCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastRxCount : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastRxCount()
        : SubscribeAttribute("packet-multicast-rx-count")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePacketMulticastRxCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.PacketMulticastRxCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PacketMulticastTxCount
 */
class ReadWiFiNetworkDiagnosticsPacketMulticastTxCount : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsPacketMulticastTxCount()
        : ReadAttribute("packet-multicast-tx-count")
    {
    }

    ~ReadWiFiNetworkDiagnosticsPacketMulticastTxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributePacketMulticastTxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.PacketMulticastTxCount response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics PacketMulticastTxCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastTxCount : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastTxCount()
        : SubscribeAttribute("packet-multicast-tx-count")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastTxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePacketMulticastTxCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.PacketMulticastTxCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PacketUnicastRxCount
 */
class ReadWiFiNetworkDiagnosticsPacketUnicastRxCount : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsPacketUnicastRxCount()
        : ReadAttribute("packet-unicast-rx-count")
    {
    }

    ~ReadWiFiNetworkDiagnosticsPacketUnicastRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributePacketUnicastRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.PacketUnicastRxCount response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics PacketUnicastRxCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastRxCount : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastRxCount()
        : SubscribeAttribute("packet-unicast-rx-count")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePacketUnicastRxCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.PacketUnicastRxCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PacketUnicastTxCount
 */
class ReadWiFiNetworkDiagnosticsPacketUnicastTxCount : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsPacketUnicastTxCount()
        : ReadAttribute("packet-unicast-tx-count")
    {
    }

    ~ReadWiFiNetworkDiagnosticsPacketUnicastTxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributePacketUnicastTxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.PacketUnicastTxCount response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics PacketUnicastTxCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastTxCount : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastTxCount()
        : SubscribeAttribute("packet-unicast-tx-count")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastTxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePacketUnicastTxCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.PacketUnicastTxCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentMaxRate
 */
class ReadWiFiNetworkDiagnosticsCurrentMaxRate : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsCurrentMaxRate()
        : ReadAttribute("current-max-rate")
    {
    }

    ~ReadWiFiNetworkDiagnosticsCurrentMaxRate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeCurrentMaxRateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.CurrentMaxRate response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics CurrentMaxRate read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsCurrentMaxRate : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsCurrentMaxRate()
        : SubscribeAttribute("current-max-rate")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsCurrentMaxRate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentMaxRateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.CurrentMaxRate response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OverrunCount
 */
class ReadWiFiNetworkDiagnosticsOverrunCount : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsOverrunCount()
        : ReadAttribute("overrun-count")
    {
    }

    ~ReadWiFiNetworkDiagnosticsOverrunCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeOverrunCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.OverrunCount response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics OverrunCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsOverrunCount : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsOverrunCount()
        : SubscribeAttribute("overrun-count")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsOverrunCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOverrunCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.OverrunCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadWiFiNetworkDiagnosticsGeneratedCommandList : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadWiFiNetworkDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadWiFiNetworkDiagnosticsAcceptedCommandList : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadWiFiNetworkDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadWiFiNetworkDiagnosticsAttributeList : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadWiFiNetworkDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadWiFiNetworkDiagnosticsFeatureMap : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadWiFiNetworkDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadWiFiNetworkDiagnosticsClusterRevision : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadWiFiNetworkDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster EthernetNetworkDiagnostics                                  | 0x0037 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCounts                                                       |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * PHYRate                                                           | 0x0000 |
| * FullDuplex                                                        | 0x0001 |
| * PacketRxCount                                                     | 0x0002 |
| * PacketTxCount                                                     | 0x0003 |
| * TxErrCount                                                        | 0x0004 |
| * CollisionCount                                                    | 0x0005 |
| * OverrunCount                                                      | 0x0006 |
| * CarrierDetect                                                     | 0x0007 |
| * TimeSinceReset                                                    | 0x0008 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCounts
 */
class EthernetNetworkDiagnosticsResetCounts : public ClusterCommand {
public:
    EthernetNetworkDiagnosticsResetCounts()
        : ClusterCommand("reset-counts")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTREthernetNetworkDiagnosticsClusterResetCountsParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetCountsWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute PHYRate
 */
class ReadEthernetNetworkDiagnosticsPHYRate : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsPHYRate()
        : ReadAttribute("phyrate")
    {
    }

    ~ReadEthernetNetworkDiagnosticsPHYRate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributePHYRateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.PHYRate response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics PHYRate read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsPHYRate : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsPHYRate()
        : SubscribeAttribute("phyrate")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsPHYRate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePHYRateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.PHYRate response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FullDuplex
 */
class ReadEthernetNetworkDiagnosticsFullDuplex : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsFullDuplex()
        : ReadAttribute("full-duplex")
    {
    }

    ~ReadEthernetNetworkDiagnosticsFullDuplex() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeFullDuplexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.FullDuplex response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics FullDuplex read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsFullDuplex : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsFullDuplex()
        : SubscribeAttribute("full-duplex")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsFullDuplex() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFullDuplexWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.FullDuplex response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PacketRxCount
 */
class ReadEthernetNetworkDiagnosticsPacketRxCount : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsPacketRxCount()
        : ReadAttribute("packet-rx-count")
    {
    }

    ~ReadEthernetNetworkDiagnosticsPacketRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributePacketRxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.PacketRxCount response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics PacketRxCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsPacketRxCount : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsPacketRxCount()
        : SubscribeAttribute("packet-rx-count")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsPacketRxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePacketRxCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.PacketRxCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PacketTxCount
 */
class ReadEthernetNetworkDiagnosticsPacketTxCount : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsPacketTxCount()
        : ReadAttribute("packet-tx-count")
    {
    }

    ~ReadEthernetNetworkDiagnosticsPacketTxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributePacketTxCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.PacketTxCount response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics PacketTxCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsPacketTxCount : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsPacketTxCount()
        : SubscribeAttribute("packet-tx-count")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsPacketTxCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePacketTxCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.PacketTxCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TxErrCount
 */
class ReadEthernetNetworkDiagnosticsTxErrCount : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsTxErrCount()
        : ReadAttribute("tx-err-count")
    {
    }

    ~ReadEthernetNetworkDiagnosticsTxErrCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeTxErrCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.TxErrCount response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics TxErrCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsTxErrCount : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsTxErrCount()
        : SubscribeAttribute("tx-err-count")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsTxErrCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTxErrCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.TxErrCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CollisionCount
 */
class ReadEthernetNetworkDiagnosticsCollisionCount : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsCollisionCount()
        : ReadAttribute("collision-count")
    {
    }

    ~ReadEthernetNetworkDiagnosticsCollisionCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeCollisionCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.CollisionCount response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics CollisionCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsCollisionCount : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsCollisionCount()
        : SubscribeAttribute("collision-count")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsCollisionCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCollisionCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.CollisionCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OverrunCount
 */
class ReadEthernetNetworkDiagnosticsOverrunCount : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsOverrunCount()
        : ReadAttribute("overrun-count")
    {
    }

    ~ReadEthernetNetworkDiagnosticsOverrunCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeOverrunCountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.OverrunCount response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics OverrunCount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsOverrunCount : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsOverrunCount()
        : SubscribeAttribute("overrun-count")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsOverrunCount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOverrunCountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.OverrunCount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CarrierDetect
 */
class ReadEthernetNetworkDiagnosticsCarrierDetect : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsCarrierDetect()
        : ReadAttribute("carrier-detect")
    {
    }

    ~ReadEthernetNetworkDiagnosticsCarrierDetect() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeCarrierDetectWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.CarrierDetect response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics CarrierDetect read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsCarrierDetect : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsCarrierDetect()
        : SubscribeAttribute("carrier-detect")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsCarrierDetect() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCarrierDetectWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.CarrierDetect response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TimeSinceReset
 */
class ReadEthernetNetworkDiagnosticsTimeSinceReset : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsTimeSinceReset()
        : ReadAttribute("time-since-reset")
    {
    }

    ~ReadEthernetNetworkDiagnosticsTimeSinceReset() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeTimeSinceResetWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.TimeSinceReset response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics TimeSinceReset read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsTimeSinceReset : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsTimeSinceReset()
        : SubscribeAttribute("time-since-reset")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsTimeSinceReset() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTimeSinceResetWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.TimeSinceReset response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadEthernetNetworkDiagnosticsGeneratedCommandList : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadEthernetNetworkDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadEthernetNetworkDiagnosticsAcceptedCommandList : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadEthernetNetworkDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadEthernetNetworkDiagnosticsAttributeList : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadEthernetNetworkDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadEthernetNetworkDiagnosticsFeatureMap : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadEthernetNetworkDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadEthernetNetworkDiagnosticsClusterRevision : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadEthernetNetworkDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster BridgedDeviceBasicInformation                               | 0x0039 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * VendorName                                                        | 0x0001 |
| * VendorID                                                          | 0x0002 |
| * ProductName                                                       | 0x0003 |
| * NodeLabel                                                         | 0x0005 |
| * HardwareVersion                                                   | 0x0007 |
| * HardwareVersionString                                             | 0x0008 |
| * SoftwareVersion                                                   | 0x0009 |
| * SoftwareVersionString                                             | 0x000A |
| * ManufacturingDate                                                 | 0x000B |
| * PartNumber                                                        | 0x000C |
| * ProductURL                                                        | 0x000D |
| * ProductLabel                                                      | 0x000E |
| * SerialNumber                                                      | 0x000F |
| * Reachable                                                         | 0x0011 |
| * UniqueID                                                          | 0x0012 |
| * ProductAppearance                                                 | 0x0014 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * StartUp                                                           | 0x0000 |
| * ShutDown                                                          | 0x0001 |
| * Leave                                                             | 0x0002 |
| * ReachableChanged                                                  | 0x0003 |
\*----------------------------------------------------------------------------*/

/*
 * Attribute VendorName
 */
class ReadBridgedDeviceBasicInformationVendorName : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationVendorName()
        : ReadAttribute("vendor-name")
    {
    }

    ~ReadBridgedDeviceBasicInformationVendorName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeVendorNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.VendorName response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation VendorName read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationVendorName : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationVendorName()
        : SubscribeAttribute("vendor-name")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationVendorName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVendorNameWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.VendorName response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute VendorID
 */
class ReadBridgedDeviceBasicInformationVendorID : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationVendorID()
        : ReadAttribute("vendor-id")
    {
    }

    ~ReadBridgedDeviceBasicInformationVendorID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.VendorID response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation VendorID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationVendorID : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationVendorID()
        : SubscribeAttribute("vendor-id")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationVendorID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVendorIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.VendorID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductName
 */
class ReadBridgedDeviceBasicInformationProductName : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationProductName()
        : ReadAttribute("product-name")
    {
    }

    ~ReadBridgedDeviceBasicInformationProductName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeProductNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.ProductName response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation ProductName read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationProductName : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationProductName()
        : SubscribeAttribute("product-name")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationProductName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductNameWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.ProductName response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NodeLabel
 */
class ReadBridgedDeviceBasicInformationNodeLabel : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationNodeLabel()
        : ReadAttribute("node-label")
    {
    }

    ~ReadBridgedDeviceBasicInformationNodeLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeNodeLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.NodeLabel response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation NodeLabel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBridgedDeviceBasicInformationNodeLabel : public WriteAttribute {
public:
    WriteBridgedDeviceBasicInformationNodeLabel()
        : WriteAttribute("node-label")
    {
        AddArgument("attr-name", "node-label");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBridgedDeviceBasicInformationNodeLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) WriteAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeNodeLabelWithValue:value
                                           params:params
                                       completion:^(NSError * _Nullable error) {
                                           if (error != nil) {
                                               LogNSError("BridgedDeviceBasicInformation NodeLabel write Error", error);
                                           }
                                           SetCommandExitStatus(error);
                                       }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBridgedDeviceBasicInformationNodeLabel : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationNodeLabel()
        : SubscribeAttribute("node-label")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationNodeLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNodeLabelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.NodeLabel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute HardwareVersion
 */
class ReadBridgedDeviceBasicInformationHardwareVersion : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationHardwareVersion()
        : ReadAttribute("hardware-version")
    {
    }

    ~ReadBridgedDeviceBasicInformationHardwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeHardwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.HardwareVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation HardwareVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationHardwareVersion : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationHardwareVersion()
        : SubscribeAttribute("hardware-version")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationHardwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeHardwareVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.HardwareVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute HardwareVersionString
 */
class ReadBridgedDeviceBasicInformationHardwareVersionString : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationHardwareVersionString()
        : ReadAttribute("hardware-version-string")
    {
    }

    ~ReadBridgedDeviceBasicInformationHardwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeHardwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.HardwareVersionString response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation HardwareVersionString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationHardwareVersionString : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationHardwareVersionString()
        : SubscribeAttribute("hardware-version-string")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationHardwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeHardwareVersionStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.HardwareVersionString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SoftwareVersion
 */
class ReadBridgedDeviceBasicInformationSoftwareVersion : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationSoftwareVersion()
        : ReadAttribute("software-version")
    {
    }

    ~ReadBridgedDeviceBasicInformationSoftwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeSoftwareVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.SoftwareVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation SoftwareVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersion : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersion()
        : SubscribeAttribute("software-version")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSoftwareVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.SoftwareVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SoftwareVersionString
 */
class ReadBridgedDeviceBasicInformationSoftwareVersionString : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationSoftwareVersionString()
        : ReadAttribute("software-version-string")
    {
    }

    ~ReadBridgedDeviceBasicInformationSoftwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeSoftwareVersionStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.SoftwareVersionString response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation SoftwareVersionString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersionString : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersionString()
        : SubscribeAttribute("software-version-string")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersionString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSoftwareVersionStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.SoftwareVersionString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ManufacturingDate
 */
class ReadBridgedDeviceBasicInformationManufacturingDate : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationManufacturingDate()
        : ReadAttribute("manufacturing-date")
    {
    }

    ~ReadBridgedDeviceBasicInformationManufacturingDate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeManufacturingDateWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.ManufacturingDate response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation ManufacturingDate read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationManufacturingDate : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationManufacturingDate()
        : SubscribeAttribute("manufacturing-date")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationManufacturingDate() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeManufacturingDateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.ManufacturingDate response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PartNumber
 */
class ReadBridgedDeviceBasicInformationPartNumber : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationPartNumber()
        : ReadAttribute("part-number")
    {
    }

    ~ReadBridgedDeviceBasicInformationPartNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributePartNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.PartNumber response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation PartNumber read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationPartNumber : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationPartNumber()
        : SubscribeAttribute("part-number")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationPartNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePartNumberWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.PartNumber response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductURL
 */
class ReadBridgedDeviceBasicInformationProductURL : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationProductURL()
        : ReadAttribute("product-url")
    {
    }

    ~ReadBridgedDeviceBasicInformationProductURL() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeProductURLWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.ProductURL response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation ProductURL read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationProductURL : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationProductURL()
        : SubscribeAttribute("product-url")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationProductURL() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000000D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductURLWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.ProductURL response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductLabel
 */
class ReadBridgedDeviceBasicInformationProductLabel : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationProductLabel()
        : ReadAttribute("product-label")
    {
    }

    ~ReadBridgedDeviceBasicInformationProductLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeProductLabelWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.ProductLabel response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation ProductLabel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationProductLabel : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationProductLabel()
        : SubscribeAttribute("product-label")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationProductLabel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000000E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductLabelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.ProductLabel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SerialNumber
 */
class ReadBridgedDeviceBasicInformationSerialNumber : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationSerialNumber()
        : ReadAttribute("serial-number")
    {
    }

    ~ReadBridgedDeviceBasicInformationSerialNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeSerialNumberWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.SerialNumber response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation SerialNumber read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationSerialNumber : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationSerialNumber()
        : SubscribeAttribute("serial-number")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationSerialNumber() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSerialNumberWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.SerialNumber response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Reachable
 */
class ReadBridgedDeviceBasicInformationReachable : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationReachable()
        : ReadAttribute("reachable")
    {
    }

    ~ReadBridgedDeviceBasicInformationReachable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeReachableWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.Reachable response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation Reachable read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationReachable : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationReachable()
        : SubscribeAttribute("reachable")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationReachable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReachableWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.Reachable response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UniqueID
 */
class ReadBridgedDeviceBasicInformationUniqueID : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationUniqueID()
        : ReadAttribute("unique-id")
    {
    }

    ~ReadBridgedDeviceBasicInformationUniqueID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeUniqueIDWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.UniqueID response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation UniqueID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationUniqueID : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationUniqueID()
        : SubscribeAttribute("unique-id")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationUniqueID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUniqueIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.UniqueID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductAppearance
 */
class ReadBridgedDeviceBasicInformationProductAppearance : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationProductAppearance()
        : ReadAttribute("product-appearance")
    {
    }

    ~ReadBridgedDeviceBasicInformationProductAppearance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeProductAppearanceWithCompletion:^(
            MTRBridgedDeviceBasicInformationClusterProductAppearanceStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.ProductAppearance response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation ProductAppearance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationProductAppearance : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationProductAppearance()
        : SubscribeAttribute("product-appearance")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationProductAppearance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductAppearanceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(
                MTRBridgedDeviceBasicInformationClusterProductAppearanceStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.ProductAppearance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadBridgedDeviceBasicInformationGeneratedCommandList : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadBridgedDeviceBasicInformationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadBridgedDeviceBasicInformationAcceptedCommandList : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadBridgedDeviceBasicInformationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadBridgedDeviceBasicInformationAttributeList : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadBridgedDeviceBasicInformationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadBridgedDeviceBasicInformationFeatureMap : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadBridgedDeviceBasicInformationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadBridgedDeviceBasicInformationClusterRevision : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadBridgedDeviceBasicInformationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Switch                                                      | 0x003B |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * NumberOfPositions                                                 | 0x0000 |
| * CurrentPosition                                                   | 0x0001 |
| * MultiPressMax                                                     | 0x0002 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * SwitchLatched                                                     | 0x0000 |
| * InitialPress                                                      | 0x0001 |
| * LongPress                                                         | 0x0002 |
| * ShortRelease                                                      | 0x0003 |
| * LongRelease                                                       | 0x0004 |
| * MultiPressOngoing                                                 | 0x0005 |
| * MultiPressComplete                                                | 0x0006 |
\*----------------------------------------------------------------------------*/

/*
 * Attribute NumberOfPositions
 */
class ReadSwitchNumberOfPositions : public ReadAttribute {
public:
    ReadSwitchNumberOfPositions()
        : ReadAttribute("number-of-positions")
    {
    }

    ~ReadSwitchNumberOfPositions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNumberOfPositionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.NumberOfPositions response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch NumberOfPositions read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchNumberOfPositions : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchNumberOfPositions()
        : SubscribeAttribute("number-of-positions")
    {
    }

    ~SubscribeAttributeSwitchNumberOfPositions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfPositionsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.NumberOfPositions response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentPosition
 */
class ReadSwitchCurrentPosition : public ReadAttribute {
public:
    ReadSwitchCurrentPosition()
        : ReadAttribute("current-position")
    {
    }

    ~ReadSwitchCurrentPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeCurrentPositionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.CurrentPosition response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch CurrentPosition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchCurrentPosition : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchCurrentPosition()
        : SubscribeAttribute("current-position")
    {
    }

    ~SubscribeAttributeSwitchCurrentPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentPositionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.CurrentPosition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MultiPressMax
 */
class ReadSwitchMultiPressMax : public ReadAttribute {
public:
    ReadSwitchMultiPressMax()
        : ReadAttribute("multi-press-max")
    {
    }

    ~ReadSwitchMultiPressMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeMultiPressMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.MultiPressMax response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch MultiPressMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchMultiPressMax : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchMultiPressMax()
        : SubscribeAttribute("multi-press-max")
    {
    }

    ~SubscribeAttributeSwitchMultiPressMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMultiPressMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.MultiPressMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadSwitchGeneratedCommandList : public ReadAttribute {
public:
    ReadSwitchGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadSwitchGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeSwitchGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadSwitchAcceptedCommandList : public ReadAttribute {
public:
    ReadSwitchAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadSwitchAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeSwitchAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadSwitchAttributeList : public ReadAttribute {
public:
    ReadSwitchAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadSwitchAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeSwitchAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadSwitchFeatureMap : public ReadAttribute {
public:
    ReadSwitchFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadSwitchFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeSwitchFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadSwitchClusterRevision : public ReadAttribute {
public:
    ReadSwitchClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadSwitchClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeSwitchClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster AdministratorCommissioning                                  | 0x003C |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * OpenCommissioningWindow                                           |   0x00 |
| * OpenBasicCommissioningWindow                                      |   0x01 |
| * RevokeCommissioning                                               |   0x02 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * WindowStatus                                                      | 0x0000 |
| * AdminFabricIndex                                                  | 0x0001 |
| * AdminVendorId                                                     | 0x0002 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command OpenCommissioningWindow
 */
class AdministratorCommissioningOpenCommissioningWindow : public ClusterCommand {
public:
    AdministratorCommissioningOpenCommissioningWindow()
        : ClusterCommand("open-commissioning-window")
    {
        AddArgument("CommissioningTimeout", 0, UINT16_MAX, &mRequest.commissioningTimeout);
        AddArgument("PAKEPasscodeVerifier", &mRequest.PAKEPasscodeVerifier);
        AddArgument("Discriminator", 0, UINT16_MAX, &mRequest.discriminator);
        AddArgument("Iterations", 0, UINT32_MAX, &mRequest.iterations);
        AddArgument("Salt", &mRequest.salt);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRAdministratorCommissioningClusterOpenCommissioningWindowParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.commissioningTimeout = [NSNumber numberWithUnsignedShort:mRequest.commissioningTimeout];
        params.pakePasscodeVerifier = [NSData dataWithBytes:mRequest.PAKEPasscodeVerifier.data()
                                                     length:mRequest.PAKEPasscodeVerifier.size()];
        params.discriminator = [NSNumber numberWithUnsignedShort:mRequest.discriminator];
        params.iterations = [NSNumber numberWithUnsignedInt:mRequest.iterations];
        params.salt = [NSData dataWithBytes:mRequest.salt.data() length:mRequest.salt.size()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster openCommissioningWindowWithParams:params
                                            completion:^(NSError * _Nullable error) {
                                                responsesNeeded--;
                                                if (error != nil) {
                                                    mError = error;
                                                    LogNSError("Error", error);
                                                }
                                                if (responsesNeeded == 0) {
                                                    SetCommandExitStatus(mError);
                                                }
                                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::AdministratorCommissioning::Commands::OpenCommissioningWindow::Type mRequest;
};

/*
 * Command OpenBasicCommissioningWindow
 */
class AdministratorCommissioningOpenBasicCommissioningWindow : public ClusterCommand {
public:
    AdministratorCommissioningOpenBasicCommissioningWindow()
        : ClusterCommand("open-basic-commissioning-window")
    {
        AddArgument("CommissioningTimeout", 0, UINT16_MAX, &mRequest.commissioningTimeout);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRAdministratorCommissioningClusterOpenBasicCommissioningWindowParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.commissioningTimeout = [NSNumber numberWithUnsignedShort:mRequest.commissioningTimeout];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster openBasicCommissioningWindowWithParams:params
                                                 completion:^(NSError * _Nullable error) {
                                                     responsesNeeded--;
                                                     if (error != nil) {
                                                         mError = error;
                                                         LogNSError("Error", error);
                                                     }
                                                     if (responsesNeeded == 0) {
                                                         SetCommandExitStatus(mError);
                                                     }
                                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Type mRequest;
};

/*
 * Command RevokeCommissioning
 */
class AdministratorCommissioningRevokeCommissioning : public ClusterCommand {
public:
    AdministratorCommissioningRevokeCommissioning()
        : ClusterCommand("revoke-commissioning")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRAdministratorCommissioningClusterRevokeCommissioningParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster revokeCommissioningWithParams:params
                                        completion:^(NSError * _Nullable error) {
                                            responsesNeeded--;
                                            if (error != nil) {
                                                mError = error;
                                                LogNSError("Error", error);
                                            }
                                            if (responsesNeeded == 0) {
                                                SetCommandExitStatus(mError);
                                            }
                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute WindowStatus
 */
class ReadAdministratorCommissioningWindowStatus : public ReadAttribute {
public:
    ReadAdministratorCommissioningWindowStatus()
        : ReadAttribute("window-status")
    {
    }

    ~ReadAdministratorCommissioningWindowStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeWindowStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.WindowStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning WindowStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningWindowStatus : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningWindowStatus()
        : SubscribeAttribute("window-status")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningWindowStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWindowStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.WindowStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AdminFabricIndex
 */
class ReadAdministratorCommissioningAdminFabricIndex : public ReadAttribute {
public:
    ReadAdministratorCommissioningAdminFabricIndex()
        : ReadAttribute("admin-fabric-index")
    {
    }

    ~ReadAdministratorCommissioningAdminFabricIndex() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAdminFabricIndexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.AdminFabricIndex response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning AdminFabricIndex read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningAdminFabricIndex : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningAdminFabricIndex()
        : SubscribeAttribute("admin-fabric-index")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningAdminFabricIndex() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAdminFabricIndexWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.AdminFabricIndex response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AdminVendorId
 */
class ReadAdministratorCommissioningAdminVendorId : public ReadAttribute {
public:
    ReadAdministratorCommissioningAdminVendorId()
        : ReadAttribute("admin-vendor-id")
    {
    }

    ~ReadAdministratorCommissioningAdminVendorId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAdminVendorIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.AdminVendorId response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning AdminVendorId read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningAdminVendorId : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningAdminVendorId()
        : SubscribeAttribute("admin-vendor-id")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningAdminVendorId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAdminVendorIdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.AdminVendorId response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadAdministratorCommissioningGeneratedCommandList : public ReadAttribute {
public:
    ReadAdministratorCommissioningGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadAdministratorCommissioningGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadAdministratorCommissioningAcceptedCommandList : public ReadAttribute {
public:
    ReadAdministratorCommissioningAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadAdministratorCommissioningAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadAdministratorCommissioningAttributeList : public ReadAttribute {
public:
    ReadAdministratorCommissioningAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadAdministratorCommissioningAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadAdministratorCommissioningFeatureMap : public ReadAttribute {
public:
    ReadAdministratorCommissioningFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadAdministratorCommissioningFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadAdministratorCommissioningClusterRevision : public ReadAttribute {
public:
    ReadAdministratorCommissioningClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadAdministratorCommissioningClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device
                                                                                      endpointID:@(endpointId)
                                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster OperationalCredentials                                      | 0x003E |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * AttestationRequest                                                |   0x00 |
| * CertificateChainRequest                                           |   0x02 |
| * CSRRequest                                                        |   0x04 |
| * AddNOC                                                            |   0x06 |
| * UpdateNOC                                                         |   0x07 |
| * UpdateFabricLabel                                                 |   0x09 |
| * RemoveFabric                                                      |   0x0A |
| * AddTrustedRootCertificate                                         |   0x0B |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * NOCs                                                              | 0x0000 |
| * Fabrics                                                           | 0x0001 |
| * SupportedFabrics                                                  | 0x0002 |
| * CommissionedFabrics                                               | 0x0003 |
| * TrustedRootCertificates                                           | 0x0004 |
| * CurrentFabricIndex                                                | 0x0005 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command AttestationRequest
 */
class OperationalCredentialsAttestationRequest : public ClusterCommand {
public:
    OperationalCredentialsAttestationRequest()
        : ClusterCommand("attestation-request")
    {
        AddArgument("AttestationNonce", &mRequest.attestationNonce);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterAttestationRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.attestationNonce = [NSData dataWithBytes:mRequest.attestationNonce.data() length:mRequest.attestationNonce.size()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster attestationRequestWithParams:params
                                       completion:^(MTROperationalCredentialsClusterAttestationResponseParams * _Nullable values,
                                           NSError * _Nullable error) {
                                           NSLog(@"Values: %@", values);
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::AttestationRequest::Type mRequest;
};

/*
 * Command CertificateChainRequest
 */
class OperationalCredentialsCertificateChainRequest : public ClusterCommand {
public:
    OperationalCredentialsCertificateChainRequest()
        : ClusterCommand("certificate-chain-request")
    {
        AddArgument("CertificateType", 0, UINT8_MAX, &mRequest.certificateType);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterCertificateChainRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.certificateType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.certificateType)];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster certificateChainRequestWithParams:params
                                            completion:^(
                                                MTROperationalCredentialsClusterCertificateChainResponseParams * _Nullable values,
                                                NSError * _Nullable error) {
                                                NSLog(@"Values: %@", values);
                                                responsesNeeded--;
                                                if (error != nil) {
                                                    mError = error;
                                                    LogNSError("Error", error);
                                                }
                                                if (responsesNeeded == 0) {
                                                    SetCommandExitStatus(mError);
                                                }
                                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::CertificateChainRequest::Type mRequest;
};

/*
 * Command CSRRequest
 */
class OperationalCredentialsCSRRequest : public ClusterCommand {
public:
    OperationalCredentialsCSRRequest()
        : ClusterCommand("csrrequest")
    {
        AddArgument("CSRNonce", &mRequest.CSRNonce);
        AddArgument("IsForUpdateNOC", 0, 1, &mRequest.isForUpdateNOC);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterCSRRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.csrNonce = [NSData dataWithBytes:mRequest.CSRNonce.data() length:mRequest.CSRNonce.size()];
        if (mRequest.isForUpdateNOC.HasValue()) {
            params.isForUpdateNOC = [NSNumber numberWithBool:mRequest.isForUpdateNOC.Value()];
        } else {
            params.isForUpdateNOC = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster CSRRequestWithParams:params
                               completion:^(MTROperationalCredentialsClusterCSRResponseParams * _Nullable values,
                                   NSError * _Nullable error) {
                                   NSLog(@"Values: %@", values);
                                   responsesNeeded--;
                                   if (error != nil) {
                                       mError = error;
                                       LogNSError("Error", error);
                                   }
                                   if (responsesNeeded == 0) {
                                       SetCommandExitStatus(mError);
                                   }
                               }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::CSRRequest::Type mRequest;
};

/*
 * Command AddNOC
 */
class OperationalCredentialsAddNOC : public ClusterCommand {
public:
    OperationalCredentialsAddNOC()
        : ClusterCommand("add-noc")
    {
        AddArgument("NOCValue", &mRequest.NOCValue);
        AddArgument("ICACValue", &mRequest.ICACValue);
        AddArgument("IPKValue", &mRequest.IPKValue);
        AddArgument("CaseAdminSubject", 0, UINT64_MAX, &mRequest.caseAdminSubject);
        AddArgument("AdminVendorId", 0, UINT16_MAX, &mRequest.adminVendorId);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterAddNOCParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.nocValue = [NSData dataWithBytes:mRequest.NOCValue.data() length:mRequest.NOCValue.size()];
        if (mRequest.ICACValue.HasValue()) {
            params.icacValue = [NSData dataWithBytes:mRequest.ICACValue.Value().data() length:mRequest.ICACValue.Value().size()];
        } else {
            params.icacValue = nil;
        }
        params.ipkValue = [NSData dataWithBytes:mRequest.IPKValue.data() length:mRequest.IPKValue.size()];
        params.caseAdminSubject = [NSNumber numberWithUnsignedLongLong:mRequest.caseAdminSubject];
        params.adminVendorId = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.adminVendorId)];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster addNOCWithParams:params
                           completion:^(
                               MTROperationalCredentialsClusterNOCResponseParams * _Nullable values, NSError * _Nullable error) {
                               NSLog(@"Values: %@", values);
                               responsesNeeded--;
                               if (error != nil) {
                                   mError = error;
                                   LogNSError("Error", error);
                               }
                               if (responsesNeeded == 0) {
                                   SetCommandExitStatus(mError);
                               }
                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::AddNOC::Type mRequest;
};

/*
 * Command UpdateNOC
 */
class OperationalCredentialsUpdateNOC : public ClusterCommand {
public:
    OperationalCredentialsUpdateNOC()
        : ClusterCommand("update-noc")
    {
        AddArgument("NOCValue", &mRequest.NOCValue);
        AddArgument("ICACValue", &mRequest.ICACValue);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterUpdateNOCParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.nocValue = [NSData dataWithBytes:mRequest.NOCValue.data() length:mRequest.NOCValue.size()];
        if (mRequest.ICACValue.HasValue()) {
            params.icacValue = [NSData dataWithBytes:mRequest.ICACValue.Value().data() length:mRequest.ICACValue.Value().size()];
        } else {
            params.icacValue = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster updateNOCWithParams:params
                              completion:^(
                                  MTROperationalCredentialsClusterNOCResponseParams * _Nullable values, NSError * _Nullable error) {
                                  NSLog(@"Values: %@", values);
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::UpdateNOC::Type mRequest;
};

/*
 * Command UpdateFabricLabel
 */
class OperationalCredentialsUpdateFabricLabel : public ClusterCommand {
public:
    OperationalCredentialsUpdateFabricLabel()
        : ClusterCommand("update-fabric-label")
    {
        AddArgument("Label", &mRequest.label);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterUpdateFabricLabelParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.label = [[NSString alloc] initWithBytes:mRequest.label.data()
                                                length:mRequest.label.size()
                                              encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster updateFabricLabelWithParams:params
                                      completion:^(MTROperationalCredentialsClusterNOCResponseParams * _Nullable values,
                                          NSError * _Nullable error) {
                                          NSLog(@"Values: %@", values);
                                          responsesNeeded--;
                                          if (error != nil) {
                                              mError = error;
                                              LogNSError("Error", error);
                                          }
                                          if (responsesNeeded == 0) {
                                              SetCommandExitStatus(mError);
                                          }
                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::UpdateFabricLabel::Type mRequest;
};

/*
 * Command RemoveFabric
 */
class OperationalCredentialsRemoveFabric : public ClusterCommand {
public:
    OperationalCredentialsRemoveFabric()
        : ClusterCommand("remove-fabric")
    {
        AddArgument("FabricIndex", 0, UINT8_MAX, &mRequest.fabricIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterRemoveFabricParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.fabricIndex = [NSNumber numberWithUnsignedChar:mRequest.fabricIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster removeFabricWithParams:params
                                 completion:^(MTROperationalCredentialsClusterNOCResponseParams * _Nullable values,
                                     NSError * _Nullable error) {
                                     NSLog(@"Values: %@", values);
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::RemoveFabric::Type mRequest;
};

/*
 * Command AddTrustedRootCertificate
 */
class OperationalCredentialsAddTrustedRootCertificate : public ClusterCommand {
public:
    OperationalCredentialsAddTrustedRootCertificate()
        : ClusterCommand("add-trusted-root-certificate")
    {
        AddArgument("RootCACertificate", &mRequest.rootCACertificate);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) command (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTROperationalCredentialsClusterAddTrustedRootCertificateParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.rootCACertificate = [NSData dataWithBytes:mRequest.rootCACertificate.data()
                                                  length:mRequest.rootCACertificate.size()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster addTrustedRootCertificateWithParams:params
                                              completion:^(NSError * _Nullable error) {
                                                  responsesNeeded--;
                                                  if (error != nil) {
                                                      mError = error;
                                                      LogNSError("Error", error);
                                                  }
                                                  if (responsesNeeded == 0) {
                                                      SetCommandExitStatus(mError);
                                                  }
                                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::OperationalCredentials::Commands::AddTrustedRootCertificate::Type mRequest;
};

/*
 * Attribute NOCs
 */
class ReadOperationalCredentialsNOCs : public ReadAttribute {
public:
    ReadOperationalCredentialsNOCs()
        : ReadAttribute("nocs")
    {
    }

    ~ReadOperationalCredentialsNOCs() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeNOCsWithParams:params
                                  completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                      NSLog(@"OperationalCredentials.NOCs response %@", [value description]);
                                      if (error != nil) {
                                          LogNSError("OperationalCredentials NOCs read Error", error);
                                      }
                                      SetCommandExitStatus(error);
                                  }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsNOCs : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsNOCs()
        : SubscribeAttribute("nocs")
    {
    }

    ~SubscribeAttributeOperationalCredentialsNOCs() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNOCsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.NOCs response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Fabrics
 */
class ReadOperationalCredentialsFabrics : public ReadAttribute {
public:
    ReadOperationalCredentialsFabrics()
        : ReadAttribute("fabrics")
    {
    }

    ~ReadOperationalCredentialsFabrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeFabricsWithParams:params
                                     completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                         NSLog(@"OperationalCredentials.Fabrics response %@", [value description]);
                                         if (error != nil) {
                                             LogNSError("OperationalCredentials Fabrics read Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsFabrics : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsFabrics()
        : SubscribeAttribute("fabrics")
    {
    }

    ~SubscribeAttributeOperationalCredentialsFabrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFabricsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.Fabrics response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SupportedFabrics
 */
class ReadOperationalCredentialsSupportedFabrics : public ReadAttribute {
public:
    ReadOperationalCredentialsSupportedFabrics()
        : ReadAttribute("supported-fabrics")
    {
    }

    ~ReadOperationalCredentialsSupportedFabrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeSupportedFabricsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.SupportedFabrics response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials SupportedFabrics read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsSupportedFabrics : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsSupportedFabrics()
        : SubscribeAttribute("supported-fabrics")
    {
    }

    ~SubscribeAttributeOperationalCredentialsSupportedFabrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSupportedFabricsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.SupportedFabrics response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CommissionedFabrics
 */
class ReadOperationalCredentialsCommissionedFabrics : public ReadAttribute {
public:
    ReadOperationalCredentialsCommissionedFabrics()
        : ReadAttribute("commissioned-fabrics")
    {
    }

    ~ReadOperationalCredentialsCommissionedFabrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeCommissionedFabricsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.CommissionedFabrics response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials CommissionedFabrics read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsCommissionedFabrics : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsCommissionedFabrics()
        : SubscribeAttribute("commissioned-fabrics")
    {
    }

    ~SubscribeAttributeOperationalCredentialsCommissionedFabrics() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCommissionedFabricsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.CommissionedFabrics response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TrustedRootCertificates
 */
class ReadOperationalCredentialsTrustedRootCertificates : public ReadAttribute {
public:
    ReadOperationalCredentialsTrustedRootCertificates()
        : ReadAttribute("trusted-root-certificates")
    {
    }

    ~ReadOperationalCredentialsTrustedRootCertificates() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeTrustedRootCertificatesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.TrustedRootCertificates response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials TrustedRootCertificates read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsTrustedRootCertificates : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsTrustedRootCertificates()
        : SubscribeAttribute("trusted-root-certificates")
    {
    }

    ~SubscribeAttributeOperationalCredentialsTrustedRootCertificates() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTrustedRootCertificatesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.TrustedRootCertificates response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentFabricIndex
 */
class ReadOperationalCredentialsCurrentFabricIndex : public ReadAttribute {
public:
    ReadOperationalCredentialsCurrentFabricIndex()
        : ReadAttribute("current-fabric-index")
    {
    }

    ~ReadOperationalCredentialsCurrentFabricIndex() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeCurrentFabricIndexWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.CurrentFabricIndex response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials CurrentFabricIndex read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsCurrentFabricIndex : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsCurrentFabricIndex()
        : SubscribeAttribute("current-fabric-index")
    {
    }

    ~SubscribeAttributeOperationalCredentialsCurrentFabricIndex() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentFabricIndexWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.CurrentFabricIndex response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadOperationalCredentialsGeneratedCommandList : public ReadAttribute {
public:
    ReadOperationalCredentialsGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadOperationalCredentialsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeOperationalCredentialsGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadOperationalCredentialsAcceptedCommandList : public ReadAttribute {
public:
    ReadOperationalCredentialsAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadOperationalCredentialsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeOperationalCredentialsAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadOperationalCredentialsAttributeList : public ReadAttribute {
public:
    ReadOperationalCredentialsAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadOperationalCredentialsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeOperationalCredentialsAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadOperationalCredentialsFeatureMap : public ReadAttribute {
public:
    ReadOperationalCredentialsFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadOperationalCredentialsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeOperationalCredentialsFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadOperationalCredentialsClusterRevision : public ReadAttribute {
public:
    ReadOperationalCredentialsClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadOperationalCredentialsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeOperationalCredentialsClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster GroupKeyManagement                                          | 0x003F |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * KeySetWrite                                                       |   0x00 |
| * KeySetRead                                                        |   0x01 |
| * KeySetRemove                                                      |   0x03 |
| * KeySetReadAllIndices                                              |   0x04 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * GroupKeyMap                                                       | 0x0000 |
| * GroupTable                                                        | 0x0001 |
| * MaxGroupsPerFabric                                                | 0x0002 |
| * MaxGroupKeysPerFabric                                             | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command KeySetWrite
 */
class GroupKeyManagementKeySetWrite : public ClusterCommand {
public:
    GroupKeyManagementKeySetWrite()
        : ClusterCommand("key-set-write")
        , mComplex_GroupKeySet(&mRequest.groupKeySet)
    {
        AddArgument("GroupKeySet", &mComplex_GroupKeySet);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRGroupKeyManagementClusterKeySetWriteParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupKeySet = [MTRGroupKeyManagementClusterGroupKeySetStruct new];
        params.groupKeySet.groupKeySetID = [NSNumber numberWithUnsignedShort:mRequest.groupKeySet.groupKeySetID];
        params.groupKeySet.groupKeySecurityPolicy =
            [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.groupKeySet.groupKeySecurityPolicy)];
        if (mRequest.groupKeySet.epochKey0.IsNull()) {
            params.groupKeySet.epochKey0 = nil;
        } else {
            params.groupKeySet.epochKey0 = [NSData dataWithBytes:mRequest.groupKeySet.epochKey0.Value().data()
                                                          length:mRequest.groupKeySet.epochKey0.Value().size()];
        }
        if (mRequest.groupKeySet.epochStartTime0.IsNull()) {
            params.groupKeySet.epochStartTime0 = nil;
        } else {
            params.groupKeySet.epochStartTime0 = [NSNumber numberWithUnsignedLongLong:mRequest.groupKeySet.epochStartTime0.Value()];
        }
        if (mRequest.groupKeySet.epochKey1.IsNull()) {
            params.groupKeySet.epochKey1 = nil;
        } else {
            params.groupKeySet.epochKey1 = [NSData dataWithBytes:mRequest.groupKeySet.epochKey1.Value().data()
                                                          length:mRequest.groupKeySet.epochKey1.Value().size()];
        }
        if (mRequest.groupKeySet.epochStartTime1.IsNull()) {
            params.groupKeySet.epochStartTime1 = nil;
        } else {
            params.groupKeySet.epochStartTime1 = [NSNumber numberWithUnsignedLongLong:mRequest.groupKeySet.epochStartTime1.Value()];
        }
        if (mRequest.groupKeySet.epochKey2.IsNull()) {
            params.groupKeySet.epochKey2 = nil;
        } else {
            params.groupKeySet.epochKey2 = [NSData dataWithBytes:mRequest.groupKeySet.epochKey2.Value().data()
                                                          length:mRequest.groupKeySet.epochKey2.Value().size()];
        }
        if (mRequest.groupKeySet.epochStartTime2.IsNull()) {
            params.groupKeySet.epochStartTime2 = nil;
        } else {
            params.groupKeySet.epochStartTime2 = [NSNumber numberWithUnsignedLongLong:mRequest.groupKeySet.epochStartTime2.Value()];
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster keySetWriteWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::GroupKeyManagement::Commands::KeySetWrite::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::GroupKeyManagement::Structs::GroupKeySetStruct::Type> mComplex_GroupKeySet;
};

/*
 * Command KeySetRead
 */
class GroupKeyManagementKeySetRead : public ClusterCommand {
public:
    GroupKeyManagementKeySetRead()
        : ClusterCommand("key-set-read")
    {
        AddArgument("GroupKeySetID", 0, UINT16_MAX, &mRequest.groupKeySetID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRGroupKeyManagementClusterKeySetReadParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupKeySetID = [NSNumber numberWithUnsignedShort:mRequest.groupKeySetID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster keySetReadWithParams:params
                               completion:^(MTRGroupKeyManagementClusterKeySetReadResponseParams * _Nullable values,
                                   NSError * _Nullable error) {
                                   NSLog(@"Values: %@", values);
                                   responsesNeeded--;
                                   if (error != nil) {
                                       mError = error;
                                       LogNSError("Error", error);
                                   }
                                   if (responsesNeeded == 0) {
                                       SetCommandExitStatus(mError);
                                   }
                               }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::GroupKeyManagement::Commands::KeySetRead::Type mRequest;
};

/*
 * Command KeySetRemove
 */
class GroupKeyManagementKeySetRemove : public ClusterCommand {
public:
    GroupKeyManagementKeySetRemove()
        : ClusterCommand("key-set-remove")
    {
        AddArgument("GroupKeySetID", 0, UINT16_MAX, &mRequest.groupKeySetID);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRGroupKeyManagementClusterKeySetRemoveParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.groupKeySetID = [NSNumber numberWithUnsignedShort:mRequest.groupKeySetID];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster keySetRemoveWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::GroupKeyManagement::Commands::KeySetRemove::Type mRequest;
};

/*
 * Command KeySetReadAllIndices
 */
class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand {
public:
    GroupKeyManagementKeySetReadAllIndices()
        : ClusterCommand("key-set-read-all-indices")
        , mComplex_GroupKeySetIDs(&mRequest.groupKeySetIDs)
    {
        AddArgument("GroupKeySetIDs", &mComplex_GroupKeySetIDs);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRGroupKeyManagementClusterKeySetReadAllIndicesParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.groupKeySetIDs) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithUnsignedShort:entry_0];
                [array_0 addObject:newElement_0];
            }
            params.groupKeySetIDs = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                keySetReadAllIndicesWithParams:params
                                    completion:^(MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseParams * _Nullable values,
                                        NSError * _Nullable error) {
                                        NSLog(@"Values: %@", values);
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::GroupKeyManagement::Commands::KeySetReadAllIndices::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const uint16_t>> mComplex_GroupKeySetIDs;
};

/*
 * Attribute GroupKeyMap
 */
class ReadGroupKeyManagementGroupKeyMap : public ReadAttribute {
public:
    ReadGroupKeyManagementGroupKeyMap()
        : ReadAttribute("group-key-map")
    {
    }

    ~ReadGroupKeyManagementGroupKeyMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeGroupKeyMapWithParams:params
                                         completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                             NSLog(@"GroupKeyManagement.GroupKeyMap response %@", [value description]);
                                             if (error != nil) {
                                                 LogNSError("GroupKeyManagement GroupKeyMap read Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }
};

class WriteGroupKeyManagementGroupKeyMap : public WriteAttribute {
public:
    WriteGroupKeyManagementGroupKeyMap()
        : WriteAttribute("group-key-map")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "group-key-map");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteGroupKeyManagementGroupKeyMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRGroupKeyManagementClusterGroupKeyMapStruct * newElement_0;
                newElement_0 = [MTRGroupKeyManagementClusterGroupKeyMapStruct new];
                newElement_0.groupId = [NSNumber numberWithUnsignedShort:entry_0.groupId];
                newElement_0.groupKeySetID = [NSNumber numberWithUnsignedShort:entry_0.groupKeySetID];
                newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeGroupKeyMapWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("GroupKeyManagement GroupKeyMap write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::GroupKeyManagement::Structs::GroupKeyMapStruct::Type> mValue;
    TypedComplexArgument<
        chip::app::DataModel::List<const chip::app::Clusters::GroupKeyManagement::Structs::GroupKeyMapStruct::Type>>
        mComplex;
};

class SubscribeAttributeGroupKeyManagementGroupKeyMap : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementGroupKeyMap()
        : SubscribeAttribute("group-key-map")
    {
    }

    ~SubscribeAttributeGroupKeyManagementGroupKeyMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGroupKeyMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.GroupKeyMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GroupTable
 */
class ReadGroupKeyManagementGroupTable : public ReadAttribute {
public:
    ReadGroupKeyManagementGroupTable()
        : ReadAttribute("group-table")
    {
    }

    ~ReadGroupKeyManagementGroupTable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeGroupTableWithParams:params
                                        completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                            NSLog(@"GroupKeyManagement.GroupTable response %@", [value description]);
                                            if (error != nil) {
                                                LogNSError("GroupKeyManagement GroupTable read Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementGroupTable : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementGroupTable()
        : SubscribeAttribute("group-table")
    {
    }

    ~SubscribeAttributeGroupKeyManagementGroupTable() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGroupTableWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.GroupTable response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxGroupsPerFabric
 */
class ReadGroupKeyManagementMaxGroupsPerFabric : public ReadAttribute {
public:
    ReadGroupKeyManagementMaxGroupsPerFabric()
        : ReadAttribute("max-groups-per-fabric")
    {
    }

    ~ReadGroupKeyManagementMaxGroupsPerFabric() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeMaxGroupsPerFabricWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.MaxGroupsPerFabric response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement MaxGroupsPerFabric read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementMaxGroupsPerFabric : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementMaxGroupsPerFabric()
        : SubscribeAttribute("max-groups-per-fabric")
    {
    }

    ~SubscribeAttributeGroupKeyManagementMaxGroupsPerFabric() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxGroupsPerFabricWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.MaxGroupsPerFabric response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxGroupKeysPerFabric
 */
class ReadGroupKeyManagementMaxGroupKeysPerFabric : public ReadAttribute {
public:
    ReadGroupKeyManagementMaxGroupKeysPerFabric()
        : ReadAttribute("max-group-keys-per-fabric")
    {
    }

    ~ReadGroupKeyManagementMaxGroupKeysPerFabric() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeMaxGroupKeysPerFabricWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.MaxGroupKeysPerFabric response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement MaxGroupKeysPerFabric read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementMaxGroupKeysPerFabric : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementMaxGroupKeysPerFabric()
        : SubscribeAttribute("max-group-keys-per-fabric")
    {
    }

    ~SubscribeAttributeGroupKeyManagementMaxGroupKeysPerFabric() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxGroupKeysPerFabricWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.MaxGroupKeysPerFabric response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadGroupKeyManagementGeneratedCommandList : public ReadAttribute {
public:
    ReadGroupKeyManagementGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadGroupKeyManagementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeGroupKeyManagementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadGroupKeyManagementAcceptedCommandList : public ReadAttribute {
public:
    ReadGroupKeyManagementAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadGroupKeyManagementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeGroupKeyManagementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadGroupKeyManagementAttributeList : public ReadAttribute {
public:
    ReadGroupKeyManagementAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadGroupKeyManagementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeGroupKeyManagementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadGroupKeyManagementFeatureMap : public ReadAttribute {
public:
    ReadGroupKeyManagementFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadGroupKeyManagementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeGroupKeyManagementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadGroupKeyManagementClusterRevision : public ReadAttribute {
public:
    ReadGroupKeyManagementClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadGroupKeyManagementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeGroupKeyManagementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster FixedLabel                                                  | 0x0040 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * LabelList                                                         | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute LabelList
 */
class ReadFixedLabelLabelList : public ReadAttribute {
public:
    ReadFixedLabelLabelList()
        : ReadAttribute("label-list")
    {
    }

    ~ReadFixedLabelLabelList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeLabelListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FixedLabel.LabelList response %@", [value description]);
            if (error != nil) {
                LogNSError("FixedLabel LabelList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFixedLabelLabelList : public SubscribeAttribute {
public:
    SubscribeAttributeFixedLabelLabelList()
        : SubscribeAttribute("label-list")
    {
    }

    ~SubscribeAttributeFixedLabelLabelList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLabelListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FixedLabel.LabelList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadFixedLabelGeneratedCommandList : public ReadAttribute {
public:
    ReadFixedLabelGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadFixedLabelGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FixedLabel.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FixedLabel GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFixedLabelGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFixedLabelGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeFixedLabelGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FixedLabel.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadFixedLabelAcceptedCommandList : public ReadAttribute {
public:
    ReadFixedLabelAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadFixedLabelAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FixedLabel.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FixedLabel AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFixedLabelAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFixedLabelAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeFixedLabelAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FixedLabel.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadFixedLabelAttributeList : public ReadAttribute {
public:
    ReadFixedLabelAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadFixedLabelAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FixedLabel.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("FixedLabel AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFixedLabelAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeFixedLabelAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeFixedLabelAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FixedLabel.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadFixedLabelFeatureMap : public ReadAttribute {
public:
    ReadFixedLabelFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadFixedLabelFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FixedLabel.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("FixedLabel FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFixedLabelFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeFixedLabelFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeFixedLabelFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FixedLabel.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadFixedLabelClusterRevision : public ReadAttribute {
public:
    ReadFixedLabelClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadFixedLabelClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FixedLabel.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("FixedLabel ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFixedLabelClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeFixedLabelClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeFixedLabelClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FixedLabel.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster UserLabel                                                   | 0x0041 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * LabelList                                                         | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute LabelList
 */
class ReadUserLabelLabelList : public ReadAttribute {
public:
    ReadUserLabelLabelList()
        : ReadAttribute("label-list")
    {
    }

    ~ReadUserLabelLabelList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeLabelListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UserLabel.LabelList response %@", [value description]);
            if (error != nil) {
                LogNSError("UserLabel LabelList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUserLabelLabelList : public WriteAttribute {
public:
    WriteUserLabelLabelList()
        : WriteAttribute("label-list")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "label-list");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUserLabelLabelList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRUserLabelClusterLabelStruct * newElement_0;
                newElement_0 = [MTRUserLabelClusterLabelStruct new];
                newElement_0.label = [[NSString alloc] initWithBytes:entry_0.label.data()
                                                              length:entry_0.label.size()
                                                            encoding:NSUTF8StringEncoding];
                newElement_0.value = [[NSString alloc] initWithBytes:entry_0.value.data()
                                                              length:entry_0.value.size()
                                                            encoding:NSUTF8StringEncoding];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeLabelListWithValue:value
                                           params:params
                                       completion:^(NSError * _Nullable error) {
                                           if (error != nil) {
                                               LogNSError("UserLabel LabelList write Error", error);
                                           }
                                           SetCommandExitStatus(error);
                                       }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::UserLabel::Structs::LabelStruct::Type> mValue;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UserLabel::Structs::LabelStruct::Type>> mComplex;
};

class SubscribeAttributeUserLabelLabelList : public SubscribeAttribute {
public:
    SubscribeAttributeUserLabelLabelList()
        : SubscribeAttribute("label-list")
    {
    }

    ~SubscribeAttributeUserLabelLabelList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLabelListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UserLabel.LabelList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadUserLabelGeneratedCommandList : public ReadAttribute {
public:
    ReadUserLabelGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadUserLabelGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UserLabel.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UserLabel GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUserLabelGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUserLabelGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeUserLabelGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UserLabel.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadUserLabelAcceptedCommandList : public ReadAttribute {
public:
    ReadUserLabelAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadUserLabelAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UserLabel.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UserLabel AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUserLabelAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUserLabelAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeUserLabelAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UserLabel.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadUserLabelAttributeList : public ReadAttribute {
public:
    ReadUserLabelAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadUserLabelAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UserLabel.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("UserLabel AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUserLabelAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeUserLabelAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeUserLabelAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UserLabel.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadUserLabelFeatureMap : public ReadAttribute {
public:
    ReadUserLabelFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadUserLabelFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UserLabel.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("UserLabel FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUserLabelFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeUserLabelFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeUserLabelFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UserLabel.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadUserLabelClusterRevision : public ReadAttribute {
public:
    ReadUserLabelClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadUserLabelClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UserLabel.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("UserLabel ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUserLabelClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeUserLabelClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeUserLabelClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UserLabel.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster BooleanState                                                | 0x0045 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * StateValue                                                        | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * StateChange                                                       | 0x0000 |
\*----------------------------------------------------------------------------*/

/*
 * Attribute StateValue
 */
class ReadBooleanStateStateValue : public ReadAttribute {
public:
    ReadBooleanStateStateValue()
        : ReadAttribute("state-value")
    {
    }

    ~ReadBooleanStateStateValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeStateValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BooleanState.StateValue response %@", [value description]);
            if (error != nil) {
                LogNSError("BooleanState StateValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBooleanStateStateValue : public SubscribeAttribute {
public:
    SubscribeAttributeBooleanStateStateValue()
        : SubscribeAttribute("state-value")
    {
    }

    ~SubscribeAttributeBooleanStateStateValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStateValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BooleanState.StateValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadBooleanStateGeneratedCommandList : public ReadAttribute {
public:
    ReadBooleanStateGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadBooleanStateGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BooleanState.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BooleanState GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBooleanStateGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBooleanStateGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeBooleanStateGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BooleanState.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadBooleanStateAcceptedCommandList : public ReadAttribute {
public:
    ReadBooleanStateAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadBooleanStateAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BooleanState.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BooleanState AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBooleanStateAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBooleanStateAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeBooleanStateAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BooleanState.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadBooleanStateAttributeList : public ReadAttribute {
public:
    ReadBooleanStateAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadBooleanStateAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BooleanState.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("BooleanState AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBooleanStateAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeBooleanStateAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeBooleanStateAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BooleanState.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadBooleanStateFeatureMap : public ReadAttribute {
public:
    ReadBooleanStateFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadBooleanStateFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BooleanState.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("BooleanState FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBooleanStateFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeBooleanStateFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeBooleanStateFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BooleanState.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadBooleanStateClusterRevision : public ReadAttribute {
public:
    ReadBooleanStateClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadBooleanStateClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BooleanState.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("BooleanState ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBooleanStateClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBooleanStateClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeBooleanStateClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BooleanState.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ModeSelect                                                  | 0x0050 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ChangeToMode                                                      |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Description                                                       | 0x0000 |
| * StandardNamespace                                                 | 0x0001 |
| * SupportedModes                                                    | 0x0002 |
| * CurrentMode                                                       | 0x0003 |
| * StartUpMode                                                       | 0x0004 |
| * OnMode                                                            | 0x0005 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ChangeToMode
 */
class ModeSelectChangeToMode : public ClusterCommand {
public:
    ModeSelectChangeToMode()
        : ClusterCommand("change-to-mode")
    {
        AddArgument("NewMode", 0, UINT8_MAX, &mRequest.newMode);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRModeSelectClusterChangeToModeParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.newMode = [NSNumber numberWithUnsignedChar:mRequest.newMode];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster changeToModeWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ModeSelect::Commands::ChangeToMode::Type mRequest;
};

/*
 * Attribute Description
 */
class ReadModeSelectDescription : public ReadAttribute {
public:
    ReadModeSelectDescription()
        : ReadAttribute("description")
    {
    }

    ~ReadModeSelectDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeDescriptionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.Description response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect Description read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectDescription : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectDescription()
        : SubscribeAttribute("description")
    {
    }

    ~SubscribeAttributeModeSelectDescription() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDescriptionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.Description response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StandardNamespace
 */
class ReadModeSelectStandardNamespace : public ReadAttribute {
public:
    ReadModeSelectStandardNamespace()
        : ReadAttribute("standard-namespace")
    {
    }

    ~ReadModeSelectStandardNamespace() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeStandardNamespaceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.StandardNamespace response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect StandardNamespace read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectStandardNamespace : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectStandardNamespace()
        : SubscribeAttribute("standard-namespace")
    {
    }

    ~SubscribeAttributeModeSelectStandardNamespace() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStandardNamespaceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.StandardNamespace response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SupportedModes
 */
class ReadModeSelectSupportedModes : public ReadAttribute {
public:
    ReadModeSelectSupportedModes()
        : ReadAttribute("supported-modes")
    {
    }

    ~ReadModeSelectSupportedModes() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSupportedModesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.SupportedModes response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect SupportedModes read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectSupportedModes : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectSupportedModes()
        : SubscribeAttribute("supported-modes")
    {
    }

    ~SubscribeAttributeModeSelectSupportedModes() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSupportedModesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.SupportedModes response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentMode
 */
class ReadModeSelectCurrentMode : public ReadAttribute {
public:
    ReadModeSelectCurrentMode()
        : ReadAttribute("current-mode")
    {
    }

    ~ReadModeSelectCurrentMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeCurrentModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.CurrentMode response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect CurrentMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectCurrentMode : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectCurrentMode()
        : SubscribeAttribute("current-mode")
    {
    }

    ~SubscribeAttributeModeSelectCurrentMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.CurrentMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StartUpMode
 */
class ReadModeSelectStartUpMode : public ReadAttribute {
public:
    ReadModeSelectStartUpMode()
        : ReadAttribute("start-up-mode")
    {
    }

    ~ReadModeSelectStartUpMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeStartUpModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.StartUpMode response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect StartUpMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteModeSelectStartUpMode : public WriteAttribute {
public:
    WriteModeSelectStartUpMode()
        : WriteAttribute("start-up-mode")
    {
        AddArgument("attr-name", "start-up-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteModeSelectStartUpMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) WriteAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeStartUpModeWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("ModeSelect StartUpMode write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeModeSelectStartUpMode : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectStartUpMode()
        : SubscribeAttribute("start-up-mode")
    {
    }

    ~SubscribeAttributeModeSelectStartUpMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStartUpModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.StartUpMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OnMode
 */
class ReadModeSelectOnMode : public ReadAttribute {
public:
    ReadModeSelectOnMode()
        : ReadAttribute("on-mode")
    {
    }

    ~ReadModeSelectOnMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOnModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.OnMode response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect OnMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteModeSelectOnMode : public WriteAttribute {
public:
    WriteModeSelectOnMode()
        : WriteAttribute("on-mode")
    {
        AddArgument("attr-name", "on-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteModeSelectOnMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) WriteAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOnModeWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("ModeSelect OnMode write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeModeSelectOnMode : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectOnMode()
        : SubscribeAttribute("on-mode")
    {
    }

    ~SubscribeAttributeModeSelectOnMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOnModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.OnMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadModeSelectGeneratedCommandList : public ReadAttribute {
public:
    ReadModeSelectGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadModeSelectGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeModeSelectGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadModeSelectAcceptedCommandList : public ReadAttribute {
public:
    ReadModeSelectAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadModeSelectAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeModeSelectAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadModeSelectAttributeList : public ReadAttribute {
public:
    ReadModeSelectAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadModeSelectAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeModeSelectAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadModeSelectFeatureMap : public ReadAttribute {
public:
    ReadModeSelectFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadModeSelectFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeModeSelectFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadModeSelectClusterRevision : public ReadAttribute {
public:
    ReadModeSelectClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadModeSelectClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeModeSelectClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster HepaFilterMonitoring                                        | 0x0071 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class HepaFilterMonitoringResetCondition : public ClusterCommand {
public:
    HepaFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRHEPAFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadHepaFilterMonitoringCondition : public ReadAttribute {
public:
    ReadHepaFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadHepaFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadHepaFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadHepaFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadHepaFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadHepaFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadHepaFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadHepaFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadHepaFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadHepaFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadHepaFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadHepaFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadHepaFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadHepaFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadHepaFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadHepaFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadHepaFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadHepaFilterMonitoringEventList : public ReadAttribute {
public:
    ReadHepaFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadHepaFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadHepaFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadHepaFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadHepaFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadHepaFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadHepaFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadHepaFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadHepaFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadHepaFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadHepaFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"HEPAFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("HEPAFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeHepaFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeHepaFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeHepaFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000071) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"HEPAFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ActivatedCarbonFilterMonitoring                             | 0x0072 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class ActivatedCarbonFilterMonitoringResetCondition : public ClusterCommand {
public:
    ActivatedCarbonFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRActivatedCarbonFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadActivatedCarbonFilterMonitoringCondition : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadActivatedCarbonFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadActivatedCarbonFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadActivatedCarbonFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadActivatedCarbonFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadActivatedCarbonFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadActivatedCarbonFilterMonitoringEventList : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadActivatedCarbonFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadActivatedCarbonFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadActivatedCarbonFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadActivatedCarbonFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadActivatedCarbonFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ActivatedCarbonFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ActivatedCarbonFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActivatedCarbonFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeActivatedCarbonFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeActivatedCarbonFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000072) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device
                                                                                           endpointID:@(endpointId)
                                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ActivatedCarbonFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster CeramicFilterMonitoring                                     | 0x0073 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class CeramicFilterMonitoringResetCondition : public ClusterCommand {
public:
    CeramicFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRCeramicFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadCeramicFilterMonitoringCondition : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadCeramicFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadCeramicFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadCeramicFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadCeramicFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadCeramicFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadCeramicFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadCeramicFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadCeramicFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadCeramicFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadCeramicFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadCeramicFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadCeramicFilterMonitoringEventList : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadCeramicFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadCeramicFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadCeramicFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadCeramicFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadCeramicFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadCeramicFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadCeramicFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadCeramicFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"CeramicFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("CeramicFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeCeramicFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeCeramicFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeCeramicFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000073) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterCeramicFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"CeramicFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ElectrostaticFilterMonitoring                               | 0x0074 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class ElectrostaticFilterMonitoringResetCondition : public ClusterCommand {
public:
    ElectrostaticFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRElectrostaticFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadElectrostaticFilterMonitoringCondition : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadElectrostaticFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadElectrostaticFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadElectrostaticFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadElectrostaticFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadElectrostaticFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadElectrostaticFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadElectrostaticFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadElectrostaticFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadElectrostaticFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadElectrostaticFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadElectrostaticFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadElectrostaticFilterMonitoringEventList : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadElectrostaticFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadElectrostaticFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadElectrostaticFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadElectrostaticFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadElectrostaticFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadElectrostaticFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadElectrostaticFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadElectrostaticFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectrostaticFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectrostaticFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectrostaticFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeElectrostaticFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeElectrostaticFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000074) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectrostaticFilterMonitoring alloc] initWithDevice:device
                                                                                         endpointID:@(endpointId)
                                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectrostaticFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster UvFilterMonitoring                                          | 0x0075 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class UvFilterMonitoringResetCondition : public ClusterCommand {
public:
    UvFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRUVFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadUvFilterMonitoringCondition : public ReadAttribute {
public:
    ReadUvFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadUvFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadUvFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadUvFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadUvFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadUvFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadUvFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadUvFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadUvFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadUvFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadUvFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadUvFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadUvFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadUvFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadUvFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadUvFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadUvFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadUvFilterMonitoringEventList : public ReadAttribute {
public:
    ReadUvFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadUvFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadUvFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadUvFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadUvFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadUvFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadUvFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadUvFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadUvFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadUvFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadUvFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UVFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("UVFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUvFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeUvFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeUvFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000075) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUVFilterMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UVFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster IonizingFilterMonitoring                                    | 0x0076 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class IonizingFilterMonitoringResetCondition : public ClusterCommand {
public:
    IonizingFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRIonizingFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadIonizingFilterMonitoringCondition : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadIonizingFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadIonizingFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadIonizingFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadIonizingFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadIonizingFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadIonizingFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadIonizingFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadIonizingFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadIonizingFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadIonizingFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadIonizingFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadIonizingFilterMonitoringEventList : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadIonizingFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadIonizingFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadIonizingFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadIonizingFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadIonizingFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadIonizingFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadIonizingFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadIonizingFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IonizingFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("IonizingFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIonizingFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeIonizingFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeIonizingFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000076) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIonizingFilterMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IonizingFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ZeoliteFilterMonitoring                                     | 0x0077 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class ZeoliteFilterMonitoringResetCondition : public ClusterCommand {
public:
    ZeoliteFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRZeoliteFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadZeoliteFilterMonitoringCondition : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadZeoliteFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadZeoliteFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadZeoliteFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadZeoliteFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadZeoliteFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadZeoliteFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadZeoliteFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadZeoliteFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadZeoliteFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadZeoliteFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadZeoliteFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadZeoliteFilterMonitoringEventList : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadZeoliteFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadZeoliteFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadZeoliteFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadZeoliteFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadZeoliteFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadZeoliteFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadZeoliteFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadZeoliteFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ZeoliteFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ZeoliteFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeZeoliteFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeZeoliteFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeZeoliteFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000077) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterZeoliteFilterMonitoring alloc] initWithDevice:device
                                                                                   endpointID:@(endpointId)
                                                                                        queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ZeoliteFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster OzoneFilterMonitoring                                       | 0x0078 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class OzoneFilterMonitoringResetCondition : public ClusterCommand {
public:
    OzoneFilterMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTROzoneFilterMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadOzoneFilterMonitoringCondition : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadOzoneFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadOzoneFilterMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadOzoneFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadOzoneFilterMonitoringChangeIndication : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadOzoneFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadOzoneFilterMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadOzoneFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadOzoneFilterMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadOzoneFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadOzoneFilterMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadOzoneFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadOzoneFilterMonitoringEventList : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadOzoneFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadOzoneFilterMonitoringAttributeList : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadOzoneFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadOzoneFilterMonitoringFeatureMap : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadOzoneFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadOzoneFilterMonitoringClusterRevision : public ReadAttribute {
public:
    ReadOzoneFilterMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadOzoneFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OzoneFilterMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("OzoneFilterMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOzoneFilterMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeOzoneFilterMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeOzoneFilterMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000078) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOzoneFilterMonitoring alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OzoneFilterMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster WaterTankMonitoring                                         | 0x0079 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class WaterTankMonitoringResetCondition : public ClusterCommand {
public:
    WaterTankMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRWaterTankMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadWaterTankMonitoringCondition : public ReadAttribute {
public:
    ReadWaterTankMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadWaterTankMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadWaterTankMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadWaterTankMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadWaterTankMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadWaterTankMonitoringChangeIndication : public ReadAttribute {
public:
    ReadWaterTankMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadWaterTankMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadWaterTankMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadWaterTankMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadWaterTankMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadWaterTankMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadWaterTankMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadWaterTankMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadWaterTankMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadWaterTankMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadWaterTankMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadWaterTankMonitoringEventList : public ReadAttribute {
public:
    ReadWaterTankMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadWaterTankMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadWaterTankMonitoringAttributeList : public ReadAttribute {
public:
    ReadWaterTankMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadWaterTankMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadWaterTankMonitoringFeatureMap : public ReadAttribute {
public:
    ReadWaterTankMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadWaterTankMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadWaterTankMonitoringClusterRevision : public ReadAttribute {
public:
    ReadWaterTankMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadWaterTankMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WaterTankMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("WaterTankMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWaterTankMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeWaterTankMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeWaterTankMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000079) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWaterTankMonitoring alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WaterTankMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster FuelTankMonitoring                                          | 0x007A |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class FuelTankMonitoringResetCondition : public ClusterCommand {
public:
    FuelTankMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRFuelTankMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadFuelTankMonitoringCondition : public ReadAttribute {
public:
    ReadFuelTankMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadFuelTankMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadFuelTankMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadFuelTankMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadFuelTankMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadFuelTankMonitoringChangeIndication : public ReadAttribute {
public:
    ReadFuelTankMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadFuelTankMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadFuelTankMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadFuelTankMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadFuelTankMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadFuelTankMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadFuelTankMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadFuelTankMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadFuelTankMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadFuelTankMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadFuelTankMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadFuelTankMonitoringEventList : public ReadAttribute {
public:
    ReadFuelTankMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadFuelTankMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadFuelTankMonitoringAttributeList : public ReadAttribute {
public:
    ReadFuelTankMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadFuelTankMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadFuelTankMonitoringFeatureMap : public ReadAttribute {
public:
    ReadFuelTankMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadFuelTankMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadFuelTankMonitoringClusterRevision : public ReadAttribute {
public:
    ReadFuelTankMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadFuelTankMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FuelTankMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("FuelTankMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFuelTankMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeFuelTankMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeFuelTankMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007A) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFuelTankMonitoring alloc] initWithDevice:device
                                                                              endpointID:@(endpointId)
                                                                                   queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FuelTankMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster InkCartridgeMonitoring                                      | 0x007B |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class InkCartridgeMonitoringResetCondition : public ClusterCommand {
public:
    InkCartridgeMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRInkCartridgeMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadInkCartridgeMonitoringCondition : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadInkCartridgeMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadInkCartridgeMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadInkCartridgeMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadInkCartridgeMonitoringChangeIndication : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadInkCartridgeMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadInkCartridgeMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadInkCartridgeMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadInkCartridgeMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadInkCartridgeMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadInkCartridgeMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadInkCartridgeMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadInkCartridgeMonitoringEventList : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadInkCartridgeMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadInkCartridgeMonitoringAttributeList : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadInkCartridgeMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadInkCartridgeMonitoringFeatureMap : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadInkCartridgeMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadInkCartridgeMonitoringClusterRevision : public ReadAttribute {
public:
    ReadInkCartridgeMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadInkCartridgeMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"InkCartridgeMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("InkCartridgeMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeInkCartridgeMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeInkCartridgeMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeInkCartridgeMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007B) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterInkCartridgeMonitoring alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"InkCartridgeMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster TonerCartridgeMonitoring                                    | 0x007C |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ResetCondition                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Condition                                                         | 0x0000 |
| * DegradationDirection                                              | 0x0001 |
| * ChangeIndication                                                  | 0x0002 |
| * InPlaceIndicator                                                  | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ResetCondition
 */
class TonerCartridgeMonitoringResetCondition : public ClusterCommand {
public:
    TonerCartridgeMonitoringResetCondition()
        : ClusterCommand("reset-condition")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRTonerCartridgeMonitoringClusterResetConditionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster resetConditionWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute Condition
 */
class ReadTonerCartridgeMonitoringCondition : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringCondition()
        : ReadAttribute("condition")
    {
    }

    ~ReadTonerCartridgeMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeConditionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.Condition response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring Condition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringCondition : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringCondition()
        : SubscribeAttribute("condition")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringCondition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConditionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.Condition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DegradationDirection
 */
class ReadTonerCartridgeMonitoringDegradationDirection : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringDegradationDirection()
        : ReadAttribute("degradation-direction")
    {
    }

    ~ReadTonerCartridgeMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeDegradationDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.DegradationDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring DegradationDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringDegradationDirection : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringDegradationDirection()
        : SubscribeAttribute("degradation-direction")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringDegradationDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDegradationDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.DegradationDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ChangeIndication
 */
class ReadTonerCartridgeMonitoringChangeIndication : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringChangeIndication()
        : ReadAttribute("change-indication")
    {
    }

    ~ReadTonerCartridgeMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeChangeIndicationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.ChangeIndication response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring ChangeIndication read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringChangeIndication : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringChangeIndication()
        : SubscribeAttribute("change-indication")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringChangeIndication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChangeIndicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.ChangeIndication response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InPlaceIndicator
 */
class ReadTonerCartridgeMonitoringInPlaceIndicator : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringInPlaceIndicator()
        : ReadAttribute("in-place-indicator")
    {
    }

    ~ReadTonerCartridgeMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeInPlaceIndicatorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.InPlaceIndicator response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring InPlaceIndicator read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringInPlaceIndicator : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringInPlaceIndicator()
        : SubscribeAttribute("in-place-indicator")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringInPlaceIndicator() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInPlaceIndicatorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.InPlaceIndicator response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadTonerCartridgeMonitoringGeneratedCommandList : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadTonerCartridgeMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadTonerCartridgeMonitoringAcceptedCommandList : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadTonerCartridgeMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadTonerCartridgeMonitoringEventList : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadTonerCartridgeMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x0000FFFA) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadTonerCartridgeMonitoringAttributeList : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadTonerCartridgeMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadTonerCartridgeMonitoringFeatureMap : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadTonerCartridgeMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadTonerCartridgeMonitoringClusterRevision : public ReadAttribute {
public:
    ReadTonerCartridgeMonitoringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadTonerCartridgeMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TonerCartridgeMonitoring.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("TonerCartridgeMonitoring ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTonerCartridgeMonitoringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeTonerCartridgeMonitoringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeTonerCartridgeMonitoringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000007C) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTonerCartridgeMonitoring alloc] initWithDevice:device
                                                                                    endpointID:@(endpointId)
                                                                                         queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TonerCartridgeMonitoring.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster DoorLock                                                    | 0x0101 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * LockDoor                                                          |   0x00 |
| * UnlockDoor                                                        |   0x01 |
| * UnlockWithTimeout                                                 |   0x03 |
| * SetWeekDaySchedule                                                |   0x0B |
| * GetWeekDaySchedule                                                |   0x0C |
| * ClearWeekDaySchedule                                              |   0x0D |
| * SetYearDaySchedule                                                |   0x0E |
| * GetYearDaySchedule                                                |   0x0F |
| * ClearYearDaySchedule                                              |   0x10 |
| * SetHolidaySchedule                                                |   0x11 |
| * GetHolidaySchedule                                                |   0x12 |
| * ClearHolidaySchedule                                              |   0x13 |
| * SetUser                                                           |   0x1A |
| * GetUser                                                           |   0x1B |
| * ClearUser                                                         |   0x1D |
| * SetCredential                                                     |   0x22 |
| * GetCredentialStatus                                               |   0x24 |
| * ClearCredential                                                   |   0x26 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * LockState                                                         | 0x0000 |
| * LockType                                                          | 0x0001 |
| * ActuatorEnabled                                                   | 0x0002 |
| * DoorState                                                         | 0x0003 |
| * DoorOpenEvents                                                    | 0x0004 |
| * DoorClosedEvents                                                  | 0x0005 |
| * OpenPeriod                                                        | 0x0006 |
| * NumberOfTotalUsersSupported                                       | 0x0011 |
| * NumberOfPINUsersSupported                                         | 0x0012 |
| * NumberOfRFIDUsersSupported                                        | 0x0013 |
| * NumberOfWeekDaySchedulesSupportedPerUser                          | 0x0014 |
| * NumberOfYearDaySchedulesSupportedPerUser                          | 0x0015 |
| * NumberOfHolidaySchedulesSupported                                 | 0x0016 |
| * MaxPINCodeLength                                                  | 0x0017 |
| * MinPINCodeLength                                                  | 0x0018 |
| * MaxRFIDCodeLength                                                 | 0x0019 |
| * MinRFIDCodeLength                                                 | 0x001A |
| * CredentialRulesSupport                                            | 0x001B |
| * NumberOfCredentialsSupportedPerUser                               | 0x001C |
| * Language                                                          | 0x0021 |
| * LEDSettings                                                       | 0x0022 |
| * AutoRelockTime                                                    | 0x0023 |
| * SoundVolume                                                       | 0x0024 |
| * OperatingMode                                                     | 0x0025 |
| * SupportedOperatingModes                                           | 0x0026 |
| * DefaultConfigurationRegister                                      | 0x0027 |
| * EnableLocalProgramming                                            | 0x0028 |
| * EnableOneTouchLocking                                             | 0x0029 |
| * EnableInsideStatusLED                                             | 0x002A |
| * EnablePrivacyModeButton                                           | 0x002B |
| * LocalProgrammingFeatures                                          | 0x002C |
| * WrongCodeEntryLimit                                               | 0x0030 |
| * UserCodeTemporaryDisableTime                                      | 0x0031 |
| * SendPINOverTheAir                                                 | 0x0032 |
| * RequirePINforRemoteOperation                                      | 0x0033 |
| * ExpiringUserTimeout                                               | 0x0035 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * DoorLockAlarm                                                     | 0x0000 |
| * DoorStateChange                                                   | 0x0001 |
| * LockOperation                                                     | 0x0002 |
| * LockOperationError                                                | 0x0003 |
| * LockUserChange                                                    | 0x0004 |
\*----------------------------------------------------------------------------*/

/*
 * Command LockDoor
 */
class DoorLockLockDoor : public ClusterCommand {
public:
    DoorLockLockDoor()
        : ClusterCommand("lock-door")
    {
        AddArgument("PINCode", &mRequest.PINCode);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterLockDoorParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.PINCode.HasValue()) {
            params.pinCode = [NSData dataWithBytes:mRequest.PINCode.Value().data() length:mRequest.PINCode.Value().size()];
        } else {
            params.pinCode = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster lockDoorWithParams:params
                             completion:^(NSError * _Nullable error) {
                                 responsesNeeded--;
                                 if (error != nil) {
                                     mError = error;
                                     LogNSError("Error", error);
                                 }
                                 if (responsesNeeded == 0) {
                                     SetCommandExitStatus(mError);
                                 }
                             }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::LockDoor::Type mRequest;
};

/*
 * Command UnlockDoor
 */
class DoorLockUnlockDoor : public ClusterCommand {
public:
    DoorLockUnlockDoor()
        : ClusterCommand("unlock-door")
    {
        AddArgument("PINCode", &mRequest.PINCode);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterUnlockDoorParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.PINCode.HasValue()) {
            params.pinCode = [NSData dataWithBytes:mRequest.PINCode.Value().data() length:mRequest.PINCode.Value().size()];
        } else {
            params.pinCode = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster unlockDoorWithParams:params
                               completion:^(NSError * _Nullable error) {
                                   responsesNeeded--;
                                   if (error != nil) {
                                       mError = error;
                                       LogNSError("Error", error);
                                   }
                                   if (responsesNeeded == 0) {
                                       SetCommandExitStatus(mError);
                                   }
                               }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::UnlockDoor::Type mRequest;
};

/*
 * Command UnlockWithTimeout
 */
class DoorLockUnlockWithTimeout : public ClusterCommand {
public:
    DoorLockUnlockWithTimeout()
        : ClusterCommand("unlock-with-timeout")
    {
        AddArgument("Timeout", 0, UINT16_MAX, &mRequest.timeout);
        AddArgument("PINCode", &mRequest.PINCode);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterUnlockWithTimeoutParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.timeout = [NSNumber numberWithUnsignedShort:mRequest.timeout];
        if (mRequest.PINCode.HasValue()) {
            params.pinCode = [NSData dataWithBytes:mRequest.PINCode.Value().data() length:mRequest.PINCode.Value().size()];
        } else {
            params.pinCode = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster unlockWithTimeoutWithParams:params
                                      completion:^(NSError * _Nullable error) {
                                          responsesNeeded--;
                                          if (error != nil) {
                                              mError = error;
                                              LogNSError("Error", error);
                                          }
                                          if (responsesNeeded == 0) {
                                              SetCommandExitStatus(mError);
                                          }
                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::UnlockWithTimeout::Type mRequest;
};

/*
 * Command SetWeekDaySchedule
 */
class DoorLockSetWeekDaySchedule : public ClusterCommand {
public:
    DoorLockSetWeekDaySchedule()
        : ClusterCommand("set-week-day-schedule")
    {
        AddArgument("WeekDayIndex", 0, UINT8_MAX, &mRequest.weekDayIndex);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        AddArgument("DaysMask", 0, UINT8_MAX, &mRequest.daysMask);
        AddArgument("StartHour", 0, UINT8_MAX, &mRequest.startHour);
        AddArgument("StartMinute", 0, UINT8_MAX, &mRequest.startMinute);
        AddArgument("EndHour", 0, UINT8_MAX, &mRequest.endHour);
        AddArgument("EndMinute", 0, UINT8_MAX, &mRequest.endMinute);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterSetWeekDayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.weekDayIndex = [NSNumber numberWithUnsignedChar:mRequest.weekDayIndex];
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        params.daysMask = [NSNumber numberWithUnsignedChar:mRequest.daysMask.Raw()];
        params.startHour = [NSNumber numberWithUnsignedChar:mRequest.startHour];
        params.startMinute = [NSNumber numberWithUnsignedChar:mRequest.startMinute];
        params.endHour = [NSNumber numberWithUnsignedChar:mRequest.endHour];
        params.endMinute = [NSNumber numberWithUnsignedChar:mRequest.endMinute];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster setWeekDayScheduleWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::SetWeekDaySchedule::Type mRequest;
};

/*
 * Command GetWeekDaySchedule
 */
class DoorLockGetWeekDaySchedule : public ClusterCommand {
public:
    DoorLockGetWeekDaySchedule()
        : ClusterCommand("get-week-day-schedule")
    {
        AddArgument("WeekDayIndex", 0, UINT8_MAX, &mRequest.weekDayIndex);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterGetWeekDayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.weekDayIndex = [NSNumber numberWithUnsignedChar:mRequest.weekDayIndex];
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getWeekDayScheduleWithParams:params
                                       completion:^(MTRDoorLockClusterGetWeekDayScheduleResponseParams * _Nullable values,
                                           NSError * _Nullable error) {
                                           NSLog(@"Values: %@", values);
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::GetWeekDaySchedule::Type mRequest;
};

/*
 * Command ClearWeekDaySchedule
 */
class DoorLockClearWeekDaySchedule : public ClusterCommand {
public:
    DoorLockClearWeekDaySchedule()
        : ClusterCommand("clear-week-day-schedule")
    {
        AddArgument("WeekDayIndex", 0, UINT8_MAX, &mRequest.weekDayIndex);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterClearWeekDayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.weekDayIndex = [NSNumber numberWithUnsignedChar:mRequest.weekDayIndex];
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster clearWeekDayScheduleWithParams:params
                                         completion:^(NSError * _Nullable error) {
                                             responsesNeeded--;
                                             if (error != nil) {
                                                 mError = error;
                                                 LogNSError("Error", error);
                                             }
                                             if (responsesNeeded == 0) {
                                                 SetCommandExitStatus(mError);
                                             }
                                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::ClearWeekDaySchedule::Type mRequest;
};

/*
 * Command SetYearDaySchedule
 */
class DoorLockSetYearDaySchedule : public ClusterCommand {
public:
    DoorLockSetYearDaySchedule()
        : ClusterCommand("set-year-day-schedule")
    {
        AddArgument("YearDayIndex", 0, UINT8_MAX, &mRequest.yearDayIndex);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        AddArgument("LocalStartTime", 0, UINT32_MAX, &mRequest.localStartTime);
        AddArgument("LocalEndTime", 0, UINT32_MAX, &mRequest.localEndTime);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterSetYearDayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.yearDayIndex = [NSNumber numberWithUnsignedChar:mRequest.yearDayIndex];
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        params.localStartTime = [NSNumber numberWithUnsignedInt:mRequest.localStartTime];
        params.localEndTime = [NSNumber numberWithUnsignedInt:mRequest.localEndTime];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster setYearDayScheduleWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::SetYearDaySchedule::Type mRequest;
};

/*
 * Command GetYearDaySchedule
 */
class DoorLockGetYearDaySchedule : public ClusterCommand {
public:
    DoorLockGetYearDaySchedule()
        : ClusterCommand("get-year-day-schedule")
    {
        AddArgument("YearDayIndex", 0, UINT8_MAX, &mRequest.yearDayIndex);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterGetYearDayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.yearDayIndex = [NSNumber numberWithUnsignedChar:mRequest.yearDayIndex];
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getYearDayScheduleWithParams:params
                                       completion:^(MTRDoorLockClusterGetYearDayScheduleResponseParams * _Nullable values,
                                           NSError * _Nullable error) {
                                           NSLog(@"Values: %@", values);
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::GetYearDaySchedule::Type mRequest;
};

/*
 * Command ClearYearDaySchedule
 */
class DoorLockClearYearDaySchedule : public ClusterCommand {
public:
    DoorLockClearYearDaySchedule()
        : ClusterCommand("clear-year-day-schedule")
    {
        AddArgument("YearDayIndex", 0, UINT8_MAX, &mRequest.yearDayIndex);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterClearYearDayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.yearDayIndex = [NSNumber numberWithUnsignedChar:mRequest.yearDayIndex];
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster clearYearDayScheduleWithParams:params
                                         completion:^(NSError * _Nullable error) {
                                             responsesNeeded--;
                                             if (error != nil) {
                                                 mError = error;
                                                 LogNSError("Error", error);
                                             }
                                             if (responsesNeeded == 0) {
                                                 SetCommandExitStatus(mError);
                                             }
                                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::ClearYearDaySchedule::Type mRequest;
};

/*
 * Command SetHolidaySchedule
 */
class DoorLockSetHolidaySchedule : public ClusterCommand {
public:
    DoorLockSetHolidaySchedule()
        : ClusterCommand("set-holiday-schedule")
    {
        AddArgument("HolidayIndex", 0, UINT8_MAX, &mRequest.holidayIndex);
        AddArgument("LocalStartTime", 0, UINT32_MAX, &mRequest.localStartTime);
        AddArgument("LocalEndTime", 0, UINT32_MAX, &mRequest.localEndTime);
        AddArgument("OperatingMode", 0, UINT8_MAX, &mRequest.operatingMode);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterSetHolidayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.holidayIndex = [NSNumber numberWithUnsignedChar:mRequest.holidayIndex];
        params.localStartTime = [NSNumber numberWithUnsignedInt:mRequest.localStartTime];
        params.localEndTime = [NSNumber numberWithUnsignedInt:mRequest.localEndTime];
        params.operatingMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.operatingMode)];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster setHolidayScheduleWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::SetHolidaySchedule::Type mRequest;
};

/*
 * Command GetHolidaySchedule
 */
class DoorLockGetHolidaySchedule : public ClusterCommand {
public:
    DoorLockGetHolidaySchedule()
        : ClusterCommand("get-holiday-schedule")
    {
        AddArgument("HolidayIndex", 0, UINT8_MAX, &mRequest.holidayIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterGetHolidayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.holidayIndex = [NSNumber numberWithUnsignedChar:mRequest.holidayIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getHolidayScheduleWithParams:params
                                       completion:^(MTRDoorLockClusterGetHolidayScheduleResponseParams * _Nullable values,
                                           NSError * _Nullable error) {
                                           NSLog(@"Values: %@", values);
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::GetHolidaySchedule::Type mRequest;
};

/*
 * Command ClearHolidaySchedule
 */
class DoorLockClearHolidaySchedule : public ClusterCommand {
public:
    DoorLockClearHolidaySchedule()
        : ClusterCommand("clear-holiday-schedule")
    {
        AddArgument("HolidayIndex", 0, UINT8_MAX, &mRequest.holidayIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterClearHolidayScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.holidayIndex = [NSNumber numberWithUnsignedChar:mRequest.holidayIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster clearHolidayScheduleWithParams:params
                                         completion:^(NSError * _Nullable error) {
                                             responsesNeeded--;
                                             if (error != nil) {
                                                 mError = error;
                                                 LogNSError("Error", error);
                                             }
                                             if (responsesNeeded == 0) {
                                                 SetCommandExitStatus(mError);
                                             }
                                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::ClearHolidaySchedule::Type mRequest;
};

/*
 * Command SetUser
 */
class DoorLockSetUser : public ClusterCommand {
public:
    DoorLockSetUser()
        : ClusterCommand("set-user")
    {
        AddArgument("OperationType", 0, UINT8_MAX, &mRequest.operationType);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        AddArgument("UserName", &mRequest.userName);
        AddArgument("UserUniqueID", 0, UINT32_MAX, &mRequest.userUniqueID);
        AddArgument("UserStatus", 0, UINT8_MAX, &mRequest.userStatus);
        AddArgument("UserType", 0, UINT8_MAX, &mRequest.userType);
        AddArgument("CredentialRule", 0, UINT8_MAX, &mRequest.credentialRule);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterSetUserParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.operationType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.operationType)];
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        if (mRequest.userName.IsNull()) {
            params.userName = nil;
        } else {
            params.userName = [[NSString alloc] initWithBytes:mRequest.userName.Value().data()
                                                       length:mRequest.userName.Value().size()
                                                     encoding:NSUTF8StringEncoding];
        }
        if (mRequest.userUniqueID.IsNull()) {
            params.userUniqueID = nil;
        } else {
            params.userUniqueID = [NSNumber numberWithUnsignedInt:mRequest.userUniqueID.Value()];
        }
        if (mRequest.userStatus.IsNull()) {
            params.userStatus = nil;
        } else {
            params.userStatus = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.userStatus.Value())];
        }
        if (mRequest.userType.IsNull()) {
            params.userType = nil;
        } else {
            params.userType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.userType.Value())];
        }
        if (mRequest.credentialRule.IsNull()) {
            params.credentialRule = nil;
        } else {
            params.credentialRule = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.credentialRule.Value())];
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster setUserWithParams:params
                            completion:^(NSError * _Nullable error) {
                                responsesNeeded--;
                                if (error != nil) {
                                    mError = error;
                                    LogNSError("Error", error);
                                }
                                if (responsesNeeded == 0) {
                                    SetCommandExitStatus(mError);
                                }
                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::SetUser::Type mRequest;
};

/*
 * Command GetUser
 */
class DoorLockGetUser : public ClusterCommand {
public:
    DoorLockGetUser()
        : ClusterCommand("get-user")
    {
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000001B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterGetUserParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getUserWithParams:params
                            completion:^(MTRDoorLockClusterGetUserResponseParams * _Nullable values, NSError * _Nullable error) {
                                NSLog(@"Values: %@", values);
                                responsesNeeded--;
                                if (error != nil) {
                                    mError = error;
                                    LogNSError("Error", error);
                                }
                                if (responsesNeeded == 0) {
                                    SetCommandExitStatus(mError);
                                }
                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::GetUser::Type mRequest;
};

/*
 * Command ClearUser
 */
class DoorLockClearUser : public ClusterCommand {
public:
    DoorLockClearUser()
        : ClusterCommand("clear-user")
    {
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x0000001D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterClearUserParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster clearUserWithParams:params
                              completion:^(NSError * _Nullable error) {
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::ClearUser::Type mRequest;
};

/*
 * Command SetCredential
 */
class DoorLockSetCredential : public ClusterCommand {
public:
    DoorLockSetCredential()
        : ClusterCommand("set-credential")
        , mComplex_Credential(&mRequest.credential)
    {
        AddArgument("OperationType", 0, UINT8_MAX, &mRequest.operationType);
        AddArgument("Credential", &mComplex_Credential);
        AddArgument("CredentialData", &mRequest.credentialData);
        AddArgument("UserIndex", 0, UINT16_MAX, &mRequest.userIndex);
        AddArgument("UserStatus", 0, UINT8_MAX, &mRequest.userStatus);
        AddArgument("UserType", 0, UINT8_MAX, &mRequest.userType);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000022) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterSetCredentialParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.operationType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.operationType)];
        params.credential = [MTRDoorLockClusterCredentialStruct new];
        params.credential.credentialType =
            [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.credential.credentialType)];
        params.credential.credentialIndex = [NSNumber numberWithUnsignedShort:mRequest.credential.credentialIndex];
        params.credentialData = [NSData dataWithBytes:mRequest.credentialData.data() length:mRequest.credentialData.size()];
        if (mRequest.userIndex.IsNull()) {
            params.userIndex = nil;
        } else {
            params.userIndex = [NSNumber numberWithUnsignedShort:mRequest.userIndex.Value()];
        }
        if (mRequest.userStatus.IsNull()) {
            params.userStatus = nil;
        } else {
            params.userStatus = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.userStatus.Value())];
        }
        if (mRequest.userType.IsNull()) {
            params.userType = nil;
        } else {
            params.userType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.userType.Value())];
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster setCredentialWithParams:params
                                  completion:^(
                                      MTRDoorLockClusterSetCredentialResponseParams * _Nullable values, NSError * _Nullable error) {
                                      NSLog(@"Values: %@", values);
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::SetCredential::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type> mComplex_Credential;
};

/*
 * Command GetCredentialStatus
 */
class DoorLockGetCredentialStatus : public ClusterCommand {
public:
    DoorLockGetCredentialStatus()
        : ClusterCommand("get-credential-status")
        , mComplex_Credential(&mRequest.credential)
    {
        AddArgument("Credential", &mComplex_Credential);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000024) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterGetCredentialStatusParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.credential = [MTRDoorLockClusterCredentialStruct new];
        params.credential.credentialType =
            [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.credential.credentialType)];
        params.credential.credentialIndex = [NSNumber numberWithUnsignedShort:mRequest.credential.credentialIndex];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getCredentialStatusWithParams:params
                                        completion:^(MTRDoorLockClusterGetCredentialStatusResponseParams * _Nullable values,
                                            NSError * _Nullable error) {
                                            NSLog(@"Values: %@", values);
                                            responsesNeeded--;
                                            if (error != nil) {
                                                mError = error;
                                                LogNSError("Error", error);
                                            }
                                            if (responsesNeeded == 0) {
                                                SetCommandExitStatus(mError);
                                            }
                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::GetCredentialStatus::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type> mComplex_Credential;
};

/*
 * Command ClearCredential
 */
class DoorLockClearCredential : public ClusterCommand {
public:
    DoorLockClearCredential()
        : ClusterCommand("clear-credential")
        , mComplex_Credential(&mRequest.credential)
    {
        AddArgument("Credential", &mComplex_Credential);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (0x00000026) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRDoorLockClusterClearCredentialParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.credential.IsNull()) {
            params.credential = nil;
        } else {
            params.credential = [MTRDoorLockClusterCredentialStruct new];
            params.credential.credentialType =
                [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.credential.Value().credentialType)];
            params.credential.credentialIndex = [NSNumber numberWithUnsignedShort:mRequest.credential.Value().credentialIndex];
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster clearCredentialWithParams:params
                                    completion:^(NSError * _Nullable error) {
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::DoorLock::Commands::ClearCredential::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type>>
        mComplex_Credential;
};

/*
 * Attribute LockState
 */
class ReadDoorLockLockState : public ReadAttribute {
public:
    ReadDoorLockLockState()
        : ReadAttribute("lock-state")
    {
    }

    ~ReadDoorLockLockState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeLockStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.LockState response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock LockState read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockLockState : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockLockState()
        : SubscribeAttribute("lock-state")
    {
    }

    ~SubscribeAttributeDoorLockLockState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLockStateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.LockState response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LockType
 */
class ReadDoorLockLockType : public ReadAttribute {
public:
    ReadDoorLockLockType()
        : ReadAttribute("lock-type")
    {
    }

    ~ReadDoorLockLockType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeLockTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.LockType response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock LockType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockLockType : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockLockType()
        : SubscribeAttribute("lock-type")
    {
    }

    ~SubscribeAttributeDoorLockLockType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLockTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.LockType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActuatorEnabled
 */
class ReadDoorLockActuatorEnabled : public ReadAttribute {
public:
    ReadDoorLockActuatorEnabled()
        : ReadAttribute("actuator-enabled")
    {
    }

    ~ReadDoorLockActuatorEnabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeActuatorEnabledWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.ActuatorEnabled response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock ActuatorEnabled read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockActuatorEnabled : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockActuatorEnabled()
        : SubscribeAttribute("actuator-enabled")
    {
    }

    ~SubscribeAttributeDoorLockActuatorEnabled() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActuatorEnabledWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.ActuatorEnabled response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DoorState
 */
class ReadDoorLockDoorState : public ReadAttribute {
public:
    ReadDoorLockDoorState()
        : ReadAttribute("door-state")
    {
    }

    ~ReadDoorLockDoorState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeDoorStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.DoorState response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock DoorState read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockDoorState : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockDoorState()
        : SubscribeAttribute("door-state")
    {
    }

    ~SubscribeAttributeDoorLockDoorState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDoorStateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.DoorState response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DoorOpenEvents
 */
class ReadDoorLockDoorOpenEvents : public ReadAttribute {
public:
    ReadDoorLockDoorOpenEvents()
        : ReadAttribute("door-open-events")
    {
    }

    ~ReadDoorLockDoorOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeDoorOpenEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.DoorOpenEvents response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock DoorOpenEvents read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockDoorOpenEvents : public WriteAttribute {
public:
    WriteDoorLockDoorOpenEvents()
        : WriteAttribute("door-open-events")
    {
        AddArgument("attr-name", "door-open-events");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockDoorOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeDoorOpenEventsWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("DoorLock DoorOpenEvents write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeDoorLockDoorOpenEvents : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockDoorOpenEvents()
        : SubscribeAttribute("door-open-events")
    {
    }

    ~SubscribeAttributeDoorLockDoorOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDoorOpenEventsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.DoorOpenEvents response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DoorClosedEvents
 */
class ReadDoorLockDoorClosedEvents : public ReadAttribute {
public:
    ReadDoorLockDoorClosedEvents()
        : ReadAttribute("door-closed-events")
    {
    }

    ~ReadDoorLockDoorClosedEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeDoorClosedEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.DoorClosedEvents response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock DoorClosedEvents read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockDoorClosedEvents : public WriteAttribute {
public:
    WriteDoorLockDoorClosedEvents()
        : WriteAttribute("door-closed-events")
    {
        AddArgument("attr-name", "door-closed-events");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockDoorClosedEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeDoorClosedEventsWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("DoorLock DoorClosedEvents write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeDoorLockDoorClosedEvents : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockDoorClosedEvents()
        : SubscribeAttribute("door-closed-events")
    {
    }

    ~SubscribeAttributeDoorLockDoorClosedEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDoorClosedEventsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.DoorClosedEvents response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OpenPeriod
 */
class ReadDoorLockOpenPeriod : public ReadAttribute {
public:
    ReadDoorLockOpenPeriod()
        : ReadAttribute("open-period")
    {
    }

    ~ReadDoorLockOpenPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeOpenPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.OpenPeriod response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock OpenPeriod read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockOpenPeriod : public WriteAttribute {
public:
    WriteDoorLockOpenPeriod()
        : WriteAttribute("open-period")
    {
        AddArgument("attr-name", "open-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockOpenPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeOpenPeriodWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("DoorLock OpenPeriod write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeDoorLockOpenPeriod : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockOpenPeriod()
        : SubscribeAttribute("open-period")
    {
    }

    ~SubscribeAttributeDoorLockOpenPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOpenPeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.OpenPeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfTotalUsersSupported
 */
class ReadDoorLockNumberOfTotalUsersSupported : public ReadAttribute {
public:
    ReadDoorLockNumberOfTotalUsersSupported()
        : ReadAttribute("number-of-total-users-supported")
    {
    }

    ~ReadDoorLockNumberOfTotalUsersSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNumberOfTotalUsersSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.NumberOfTotalUsersSupported response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock NumberOfTotalUsersSupported read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockNumberOfTotalUsersSupported : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockNumberOfTotalUsersSupported()
        : SubscribeAttribute("number-of-total-users-supported")
    {
    }

    ~SubscribeAttributeDoorLockNumberOfTotalUsersSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfTotalUsersSupportedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfTotalUsersSupported response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfPINUsersSupported
 */
class ReadDoorLockNumberOfPINUsersSupported : public ReadAttribute {
public:
    ReadDoorLockNumberOfPINUsersSupported()
        : ReadAttribute("number-of-pinusers-supported")
    {
    }

    ~ReadDoorLockNumberOfPINUsersSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNumberOfPINUsersSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.NumberOfPINUsersSupported response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock NumberOfPINUsersSupported read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockNumberOfPINUsersSupported : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockNumberOfPINUsersSupported()
        : SubscribeAttribute("number-of-pinusers-supported")
    {
    }

    ~SubscribeAttributeDoorLockNumberOfPINUsersSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfPINUsersSupportedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfPINUsersSupported response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfRFIDUsersSupported
 */
class ReadDoorLockNumberOfRFIDUsersSupported : public ReadAttribute {
public:
    ReadDoorLockNumberOfRFIDUsersSupported()
        : ReadAttribute("number-of-rfidusers-supported")
    {
    }

    ~ReadDoorLockNumberOfRFIDUsersSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNumberOfRFIDUsersSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.NumberOfRFIDUsersSupported response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock NumberOfRFIDUsersSupported read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockNumberOfRFIDUsersSupported : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockNumberOfRFIDUsersSupported()
        : SubscribeAttribute("number-of-rfidusers-supported")
    {
    }

    ~SubscribeAttributeDoorLockNumberOfRFIDUsersSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfRFIDUsersSupportedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfRFIDUsersSupported response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfWeekDaySchedulesSupportedPerUser
 */
class ReadDoorLockNumberOfWeekDaySchedulesSupportedPerUser : public ReadAttribute {
public:
    ReadDoorLockNumberOfWeekDaySchedulesSupportedPerUser()
        : ReadAttribute("number-of-week-day-schedules-supported-per-user")
    {
    }

    ~ReadDoorLockNumberOfWeekDaySchedulesSupportedPerUser() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.NumberOfWeekDaySchedulesSupportedPerUser response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock NumberOfWeekDaySchedulesSupportedPerUser read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockNumberOfWeekDaySchedulesSupportedPerUser : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockNumberOfWeekDaySchedulesSupportedPerUser()
        : SubscribeAttribute("number-of-week-day-schedules-supported-per-user")
    {
    }

    ~SubscribeAttributeDoorLockNumberOfWeekDaySchedulesSupportedPerUser() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfWeekDaySchedulesSupportedPerUserWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfWeekDaySchedulesSupportedPerUser response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfYearDaySchedulesSupportedPerUser
 */
class ReadDoorLockNumberOfYearDaySchedulesSupportedPerUser : public ReadAttribute {
public:
    ReadDoorLockNumberOfYearDaySchedulesSupportedPerUser()
        : ReadAttribute("number-of-year-day-schedules-supported-per-user")
    {
    }

    ~ReadDoorLockNumberOfYearDaySchedulesSupportedPerUser() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNumberOfYearDaySchedulesSupportedPerUserWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.NumberOfYearDaySchedulesSupportedPerUser response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock NumberOfYearDaySchedulesSupportedPerUser read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockNumberOfYearDaySchedulesSupportedPerUser : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockNumberOfYearDaySchedulesSupportedPerUser()
        : SubscribeAttribute("number-of-year-day-schedules-supported-per-user")
    {
    }

    ~SubscribeAttributeDoorLockNumberOfYearDaySchedulesSupportedPerUser() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfYearDaySchedulesSupportedPerUserWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfYearDaySchedulesSupportedPerUser response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfHolidaySchedulesSupported
 */
class ReadDoorLockNumberOfHolidaySchedulesSupported : public ReadAttribute {
public:
    ReadDoorLockNumberOfHolidaySchedulesSupported()
        : ReadAttribute("number-of-holiday-schedules-supported")
    {
    }

    ~ReadDoorLockNumberOfHolidaySchedulesSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster
            readAttributeNumberOfHolidaySchedulesSupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfHolidaySchedulesSupported response %@", [value description]);
                if (error != nil) {
                    LogNSError("DoorLock NumberOfHolidaySchedulesSupported read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockNumberOfHolidaySchedulesSupported : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockNumberOfHolidaySchedulesSupported()
        : SubscribeAttribute("number-of-holiday-schedules-supported")
    {
    }

    ~SubscribeAttributeDoorLockNumberOfHolidaySchedulesSupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfHolidaySchedulesSupportedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfHolidaySchedulesSupported response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxPINCodeLength
 */
class ReadDoorLockMaxPINCodeLength : public ReadAttribute {
public:
    ReadDoorLockMaxPINCodeLength()
        : ReadAttribute("max-pincode-length")
    {
    }

    ~ReadDoorLockMaxPINCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeMaxPINCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.MaxPINCodeLength response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock MaxPINCodeLength read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockMaxPINCodeLength : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockMaxPINCodeLength()
        : SubscribeAttribute("max-pincode-length")
    {
    }

    ~SubscribeAttributeDoorLockMaxPINCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxPINCodeLengthWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.MaxPINCodeLength response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinPINCodeLength
 */
class ReadDoorLockMinPINCodeLength : public ReadAttribute {
public:
    ReadDoorLockMinPINCodeLength()
        : ReadAttribute("min-pincode-length")
    {
    }

    ~ReadDoorLockMinPINCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000018) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeMinPINCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.MinPINCodeLength response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock MinPINCodeLength read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockMinPINCodeLength : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockMinPINCodeLength()
        : SubscribeAttribute("min-pincode-length")
    {
    }

    ~SubscribeAttributeDoorLockMinPINCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinPINCodeLengthWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.MinPINCodeLength response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxRFIDCodeLength
 */
class ReadDoorLockMaxRFIDCodeLength : public ReadAttribute {
public:
    ReadDoorLockMaxRFIDCodeLength()
        : ReadAttribute("max-rfidcode-length")
    {
    }

    ~ReadDoorLockMaxRFIDCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000019) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeMaxRFIDCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.MaxRFIDCodeLength response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock MaxRFIDCodeLength read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockMaxRFIDCodeLength : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockMaxRFIDCodeLength()
        : SubscribeAttribute("max-rfidcode-length")
    {
    }

    ~SubscribeAttributeDoorLockMaxRFIDCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxRFIDCodeLengthWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.MaxRFIDCodeLength response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinRFIDCodeLength
 */
class ReadDoorLockMinRFIDCodeLength : public ReadAttribute {
public:
    ReadDoorLockMinRFIDCodeLength()
        : ReadAttribute("min-rfidcode-length")
    {
    }

    ~ReadDoorLockMinRFIDCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeMinRFIDCodeLengthWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.MinRFIDCodeLength response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock MinRFIDCodeLength read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockMinRFIDCodeLength : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockMinRFIDCodeLength()
        : SubscribeAttribute("min-rfidcode-length")
    {
    }

    ~SubscribeAttributeDoorLockMinRFIDCodeLength() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinRFIDCodeLengthWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.MinRFIDCodeLength response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CredentialRulesSupport
 */
class ReadDoorLockCredentialRulesSupport : public ReadAttribute {
public:
    ReadDoorLockCredentialRulesSupport()
        : ReadAttribute("credential-rules-support")
    {
    }

    ~ReadDoorLockCredentialRulesSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000001B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeCredentialRulesSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.CredentialRulesSupport response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock CredentialRulesSupport read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockCredentialRulesSupport : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockCredentialRulesSupport()
        : SubscribeAttribute("credential-rules-support")
    {
    }

    ~SubscribeAttributeDoorLockCredentialRulesSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCredentialRulesSupportWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.CredentialRulesSupport response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfCredentialsSupportedPerUser
 */
class ReadDoorLockNumberOfCredentialsSupportedPerUser : public ReadAttribute {
public:
    ReadDoorLockNumberOfCredentialsSupportedPerUser()
        : ReadAttribute("number-of-credentials-supported-per-user")
    {
    }

    ~ReadDoorLockNumberOfCredentialsSupportedPerUser() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000001C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeNumberOfCredentialsSupportedPerUserWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.NumberOfCredentialsSupportedPerUser response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock NumberOfCredentialsSupportedPerUser read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockNumberOfCredentialsSupportedPerUser : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockNumberOfCredentialsSupportedPerUser()
        : SubscribeAttribute("number-of-credentials-supported-per-user")
    {
    }

    ~SubscribeAttributeDoorLockNumberOfCredentialsSupportedPerUser() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfCredentialsSupportedPerUserWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.NumberOfCredentialsSupportedPerUser response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Language
 */
class ReadDoorLockLanguage : public ReadAttribute {
public:
    ReadDoorLockLanguage()
        : ReadAttribute("language")
    {
    }

    ~ReadDoorLockLanguage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000021) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeLanguageWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.Language response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock Language read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockLanguage : public WriteAttribute {
public:
    WriteDoorLockLanguage()
        : WriteAttribute("language")
    {
        AddArgument("attr-name", "language");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockLanguage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeLanguageWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("DoorLock Language write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeDoorLockLanguage : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockLanguage()
        : SubscribeAttribute("language")
    {
    }

    ~SubscribeAttributeDoorLockLanguage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLanguageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.Language response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LEDSettings
 */
class ReadDoorLockLEDSettings : public ReadAttribute {
public:
    ReadDoorLockLEDSettings()
        : ReadAttribute("ledsettings")
    {
    }

    ~ReadDoorLockLEDSettings() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000022) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeLEDSettingsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.LEDSettings response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock LEDSettings read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockLEDSettings : public WriteAttribute {
public:
    WriteDoorLockLEDSettings()
        : WriteAttribute("ledsettings")
    {
        AddArgument("attr-name", "ledsettings");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockLEDSettings() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeLEDSettingsWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("DoorLock LEDSettings write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeDoorLockLEDSettings : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockLEDSettings()
        : SubscribeAttribute("ledsettings")
    {
    }

    ~SubscribeAttributeDoorLockLEDSettings() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLEDSettingsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.LEDSettings response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AutoRelockTime
 */
class ReadDoorLockAutoRelockTime : public ReadAttribute {
public:
    ReadDoorLockAutoRelockTime()
        : ReadAttribute("auto-relock-time")
    {
    }

    ~ReadDoorLockAutoRelockTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000023) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAutoRelockTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.AutoRelockTime response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock AutoRelockTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockAutoRelockTime : public WriteAttribute {
public:
    WriteDoorLockAutoRelockTime()
        : WriteAttribute("auto-relock-time")
    {
        AddArgument("attr-name", "auto-relock-time");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockAutoRelockTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000023) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeAutoRelockTimeWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("DoorLock AutoRelockTime write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeDoorLockAutoRelockTime : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockAutoRelockTime()
        : SubscribeAttribute("auto-relock-time")
    {
    }

    ~SubscribeAttributeDoorLockAutoRelockTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000023) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAutoRelockTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.AutoRelockTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SoundVolume
 */
class ReadDoorLockSoundVolume : public ReadAttribute {
public:
    ReadDoorLockSoundVolume()
        : ReadAttribute("sound-volume")
    {
    }

    ~ReadDoorLockSoundVolume() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000024) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeSoundVolumeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.SoundVolume response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock SoundVolume read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockSoundVolume : public WriteAttribute {
public:
    WriteDoorLockSoundVolume()
        : WriteAttribute("sound-volume")
    {
        AddArgument("attr-name", "sound-volume");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockSoundVolume() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeSoundVolumeWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("DoorLock SoundVolume write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeDoorLockSoundVolume : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockSoundVolume()
        : SubscribeAttribute("sound-volume")
    {
    }

    ~SubscribeAttributeDoorLockSoundVolume() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSoundVolumeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.SoundVolume response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OperatingMode
 */
class ReadDoorLockOperatingMode : public ReadAttribute {
public:
    ReadDoorLockOperatingMode()
        : ReadAttribute("operating-mode")
    {
    }

    ~ReadDoorLockOperatingMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000025) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeOperatingModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.OperatingMode response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock OperatingMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockOperatingMode : public WriteAttribute {
public:
    WriteDoorLockOperatingMode()
        : WriteAttribute("operating-mode")
    {
        AddArgument("attr-name", "operating-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockOperatingMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOperatingModeWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("DoorLock OperatingMode write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeDoorLockOperatingMode : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockOperatingMode()
        : SubscribeAttribute("operating-mode")
    {
    }

    ~SubscribeAttributeDoorLockOperatingMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOperatingModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.OperatingMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SupportedOperatingModes
 */
class ReadDoorLockSupportedOperatingModes : public ReadAttribute {
public:
    ReadDoorLockSupportedOperatingModes()
        : ReadAttribute("supported-operating-modes")
    {
    }

    ~ReadDoorLockSupportedOperatingModes() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000026) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeSupportedOperatingModesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.SupportedOperatingModes response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock SupportedOperatingModes read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockSupportedOperatingModes : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockSupportedOperatingModes()
        : SubscribeAttribute("supported-operating-modes")
    {
    }

    ~SubscribeAttributeDoorLockSupportedOperatingModes() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000026) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSupportedOperatingModesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.SupportedOperatingModes response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DefaultConfigurationRegister
 */
class ReadDoorLockDefaultConfigurationRegister : public ReadAttribute {
public:
    ReadDoorLockDefaultConfigurationRegister()
        : ReadAttribute("default-configuration-register")
    {
    }

    ~ReadDoorLockDefaultConfigurationRegister() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000027) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeDefaultConfigurationRegisterWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.DefaultConfigurationRegister response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock DefaultConfigurationRegister read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockDefaultConfigurationRegister : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockDefaultConfigurationRegister()
        : SubscribeAttribute("default-configuration-register")
    {
    }

    ~SubscribeAttributeDoorLockDefaultConfigurationRegister() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000027) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDefaultConfigurationRegisterWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.DefaultConfigurationRegister response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EnableLocalProgramming
 */
class ReadDoorLockEnableLocalProgramming : public ReadAttribute {
public:
    ReadDoorLockEnableLocalProgramming()
        : ReadAttribute("enable-local-programming")
    {
    }

    ~ReadDoorLockEnableLocalProgramming() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000028) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeEnableLocalProgrammingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.EnableLocalProgramming response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock EnableLocalProgramming read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockEnableLocalProgramming : public WriteAttribute {
public:
    WriteDoorLockEnableLocalProgramming()
        : WriteAttribute("enable-local-programming")
    {
        AddArgument("attr-name", "enable-local-programming");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockEnableLocalProgramming() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeEnableLocalProgrammingWithValue:value
                                                        params:params
                                                    completion:^(NSError * _Nullable error) {
                                                        if (error != nil) {
                                                            LogNSError("DoorLock EnableLocalProgramming write Error", error);
                                                        }
                                                        SetCommandExitStatus(error);
                                                    }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeDoorLockEnableLocalProgramming : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockEnableLocalProgramming()
        : SubscribeAttribute("enable-local-programming")
    {
    }

    ~SubscribeAttributeDoorLockEnableLocalProgramming() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnableLocalProgrammingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.EnableLocalProgramming response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EnableOneTouchLocking
 */
class ReadDoorLockEnableOneTouchLocking : public ReadAttribute {
public:
    ReadDoorLockEnableOneTouchLocking()
        : ReadAttribute("enable-one-touch-locking")
    {
    }

    ~ReadDoorLockEnableOneTouchLocking() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000029) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeEnableOneTouchLockingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.EnableOneTouchLocking response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock EnableOneTouchLocking read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockEnableOneTouchLocking : public WriteAttribute {
public:
    WriteDoorLockEnableOneTouchLocking()
        : WriteAttribute("enable-one-touch-locking")
    {
        AddArgument("attr-name", "enable-one-touch-locking");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockEnableOneTouchLocking() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeEnableOneTouchLockingWithValue:value
                                                       params:params
                                                   completion:^(NSError * _Nullable error) {
                                                       if (error != nil) {
                                                           LogNSError("DoorLock EnableOneTouchLocking write Error", error);
                                                       }
                                                       SetCommandExitStatus(error);
                                                   }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeDoorLockEnableOneTouchLocking : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockEnableOneTouchLocking()
        : SubscribeAttribute("enable-one-touch-locking")
    {
    }

    ~SubscribeAttributeDoorLockEnableOneTouchLocking() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnableOneTouchLockingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.EnableOneTouchLocking response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EnableInsideStatusLED
 */
class ReadDoorLockEnableInsideStatusLED : public ReadAttribute {
public:
    ReadDoorLockEnableInsideStatusLED()
        : ReadAttribute("enable-inside-status-led")
    {
    }

    ~ReadDoorLockEnableInsideStatusLED() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000002A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeEnableInsideStatusLEDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.EnableInsideStatusLED response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock EnableInsideStatusLED read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockEnableInsideStatusLED : public WriteAttribute {
public:
    WriteDoorLockEnableInsideStatusLED()
        : WriteAttribute("enable-inside-status-led")
    {
        AddArgument("attr-name", "enable-inside-status-led");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockEnableInsideStatusLED() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x0000002A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeEnableInsideStatusLEDWithValue:value
                                                       params:params
                                                   completion:^(NSError * _Nullable error) {
                                                       if (error != nil) {
                                                           LogNSError("DoorLock EnableInsideStatusLED write Error", error);
                                                       }
                                                       SetCommandExitStatus(error);
                                                   }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeDoorLockEnableInsideStatusLED : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockEnableInsideStatusLED()
        : SubscribeAttribute("enable-inside-status-led")
    {
    }

    ~SubscribeAttributeDoorLockEnableInsideStatusLED() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000002A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnableInsideStatusLEDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.EnableInsideStatusLED response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EnablePrivacyModeButton
 */
class ReadDoorLockEnablePrivacyModeButton : public ReadAttribute {
public:
    ReadDoorLockEnablePrivacyModeButton()
        : ReadAttribute("enable-privacy-mode-button")
    {
    }

    ~ReadDoorLockEnablePrivacyModeButton() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000002B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeEnablePrivacyModeButtonWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.EnablePrivacyModeButton response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock EnablePrivacyModeButton read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockEnablePrivacyModeButton : public WriteAttribute {
public:
    WriteDoorLockEnablePrivacyModeButton()
        : WriteAttribute("enable-privacy-mode-button")
    {
        AddArgument("attr-name", "enable-privacy-mode-button");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockEnablePrivacyModeButton() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x0000002B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeEnablePrivacyModeButtonWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("DoorLock EnablePrivacyModeButton write Error", error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeDoorLockEnablePrivacyModeButton : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockEnablePrivacyModeButton()
        : SubscribeAttribute("enable-privacy-mode-button")
    {
    }

    ~SubscribeAttributeDoorLockEnablePrivacyModeButton() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000002B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnablePrivacyModeButtonWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.EnablePrivacyModeButton response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LocalProgrammingFeatures
 */
class ReadDoorLockLocalProgrammingFeatures : public ReadAttribute {
public:
    ReadDoorLockLocalProgrammingFeatures()
        : ReadAttribute("local-programming-features")
    {
    }

    ~ReadDoorLockLocalProgrammingFeatures() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000002C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeLocalProgrammingFeaturesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.LocalProgrammingFeatures response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock LocalProgrammingFeatures read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockLocalProgrammingFeatures : public WriteAttribute {
public:
    WriteDoorLockLocalProgrammingFeatures()
        : WriteAttribute("local-programming-features")
    {
        AddArgument("attr-name", "local-programming-features");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockLocalProgrammingFeatures() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x0000002C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeLocalProgrammingFeaturesWithValue:value
                                                          params:params
                                                      completion:^(NSError * _Nullable error) {
                                                          if (error != nil) {
                                                              LogNSError("DoorLock LocalProgrammingFeatures write Error", error);
                                                          }
                                                          SetCommandExitStatus(error);
                                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeDoorLockLocalProgrammingFeatures : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockLocalProgrammingFeatures()
        : SubscribeAttribute("local-programming-features")
    {
    }

    ~SubscribeAttributeDoorLockLocalProgrammingFeatures() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000002C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLocalProgrammingFeaturesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.LocalProgrammingFeatures response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WrongCodeEntryLimit
 */
class ReadDoorLockWrongCodeEntryLimit : public ReadAttribute {
public:
    ReadDoorLockWrongCodeEntryLimit()
        : ReadAttribute("wrong-code-entry-limit")
    {
    }

    ~ReadDoorLockWrongCodeEntryLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000030) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeWrongCodeEntryLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.WrongCodeEntryLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock WrongCodeEntryLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockWrongCodeEntryLimit : public WriteAttribute {
public:
    WriteDoorLockWrongCodeEntryLimit()
        : WriteAttribute("wrong-code-entry-limit")
    {
        AddArgument("attr-name", "wrong-code-entry-limit");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockWrongCodeEntryLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeWrongCodeEntryLimitWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("DoorLock WrongCodeEntryLimit write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeDoorLockWrongCodeEntryLimit : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockWrongCodeEntryLimit()
        : SubscribeAttribute("wrong-code-entry-limit")
    {
    }

    ~SubscribeAttributeDoorLockWrongCodeEntryLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWrongCodeEntryLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.WrongCodeEntryLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UserCodeTemporaryDisableTime
 */
class ReadDoorLockUserCodeTemporaryDisableTime : public ReadAttribute {
public:
    ReadDoorLockUserCodeTemporaryDisableTime()
        : ReadAttribute("user-code-temporary-disable-time")
    {
    }

    ~ReadDoorLockUserCodeTemporaryDisableTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000031) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeUserCodeTemporaryDisableTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.UserCodeTemporaryDisableTime response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock UserCodeTemporaryDisableTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockUserCodeTemporaryDisableTime : public WriteAttribute {
public:
    WriteDoorLockUserCodeTemporaryDisableTime()
        : WriteAttribute("user-code-temporary-disable-time")
    {
        AddArgument("attr-name", "user-code-temporary-disable-time");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockUserCodeTemporaryDisableTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster
            writeAttributeUserCodeTemporaryDisableTimeWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("DoorLock UserCodeTemporaryDisableTime write Error", error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeDoorLockUserCodeTemporaryDisableTime : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockUserCodeTemporaryDisableTime()
        : SubscribeAttribute("user-code-temporary-disable-time")
    {
    }

    ~SubscribeAttributeDoorLockUserCodeTemporaryDisableTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUserCodeTemporaryDisableTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.UserCodeTemporaryDisableTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SendPINOverTheAir
 */
class ReadDoorLockSendPINOverTheAir : public ReadAttribute {
public:
    ReadDoorLockSendPINOverTheAir()
        : ReadAttribute("send-pinover-the-air")
    {
    }

    ~ReadDoorLockSendPINOverTheAir() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000032) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeSendPINOverTheAirWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.SendPINOverTheAir response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock SendPINOverTheAir read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockSendPINOverTheAir : public WriteAttribute {
public:
    WriteDoorLockSendPINOverTheAir()
        : WriteAttribute("send-pinover-the-air")
    {
        AddArgument("attr-name", "send-pinover-the-air");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockSendPINOverTheAir() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeSendPINOverTheAirWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("DoorLock SendPINOverTheAir write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeDoorLockSendPINOverTheAir : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockSendPINOverTheAir()
        : SubscribeAttribute("send-pinover-the-air")
    {
    }

    ~SubscribeAttributeDoorLockSendPINOverTheAir() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSendPINOverTheAirWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.SendPINOverTheAir response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RequirePINforRemoteOperation
 */
class ReadDoorLockRequirePINforRemoteOperation : public ReadAttribute {
public:
    ReadDoorLockRequirePINforRemoteOperation()
        : ReadAttribute("require-pinfor-remote-operation")
    {
    }

    ~ReadDoorLockRequirePINforRemoteOperation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000033) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeRequirePINforRemoteOperationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.RequirePINforRemoteOperation response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock RequirePINforRemoteOperation read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockRequirePINforRemoteOperation : public WriteAttribute {
public:
    WriteDoorLockRequirePINforRemoteOperation()
        : WriteAttribute("require-pinfor-remote-operation")
    {
        AddArgument("attr-name", "require-pinfor-remote-operation");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockRequirePINforRemoteOperation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000033) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster
            writeAttributeRequirePINforRemoteOperationWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("DoorLock RequirePINforRemoteOperation write Error", error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeDoorLockRequirePINforRemoteOperation : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockRequirePINforRemoteOperation()
        : SubscribeAttribute("require-pinfor-remote-operation")
    {
    }

    ~SubscribeAttributeDoorLockRequirePINforRemoteOperation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000033) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRequirePINforRemoteOperationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.RequirePINforRemoteOperation response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ExpiringUserTimeout
 */
class ReadDoorLockExpiringUserTimeout : public ReadAttribute {
public:
    ReadDoorLockExpiringUserTimeout()
        : ReadAttribute("expiring-user-timeout")
    {
    }

    ~ReadDoorLockExpiringUserTimeout() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x00000035) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeExpiringUserTimeoutWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.ExpiringUserTimeout response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock ExpiringUserTimeout read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteDoorLockExpiringUserTimeout : public WriteAttribute {
public:
    WriteDoorLockExpiringUserTimeout()
        : WriteAttribute("expiring-user-timeout")
    {
        AddArgument("attr-name", "expiring-user-timeout");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteDoorLockExpiringUserTimeout() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) WriteAttribute (0x00000035) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeExpiringUserTimeoutWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("DoorLock ExpiringUserTimeout write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeDoorLockExpiringUserTimeout : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockExpiringUserTimeout()
        : SubscribeAttribute("expiring-user-timeout")
    {
    }

    ~SubscribeAttributeDoorLockExpiringUserTimeout() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x00000035) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeExpiringUserTimeoutWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.ExpiringUserTimeout response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadDoorLockGeneratedCommandList : public ReadAttribute {
public:
    ReadDoorLockGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadDoorLockGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeDoorLockGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadDoorLockAcceptedCommandList : public ReadAttribute {
public:
    ReadDoorLockAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadDoorLockAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeDoorLockAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadDoorLockAttributeList : public ReadAttribute {
public:
    ReadDoorLockAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadDoorLockAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeDoorLockAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadDoorLockFeatureMap : public ReadAttribute {
public:
    ReadDoorLockFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadDoorLockFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeDoorLockFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadDoorLockClusterRevision : public ReadAttribute {
public:
    ReadDoorLockClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadDoorLockClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeDoorLockClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster WindowCovering                                              | 0x0102 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * UpOrOpen                                                          |   0x00 |
| * DownOrClose                                                       |   0x01 |
| * StopMotion                                                        |   0x02 |
| * GoToLiftValue                                                     |   0x04 |
| * GoToLiftPercentage                                                |   0x05 |
| * GoToTiltValue                                                     |   0x07 |
| * GoToTiltPercentage                                                |   0x08 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Type                                                              | 0x0000 |
| * PhysicalClosedLimitLift                                           | 0x0001 |
| * PhysicalClosedLimitTilt                                           | 0x0002 |
| * CurrentPositionLift                                               | 0x0003 |
| * CurrentPositionTilt                                               | 0x0004 |
| * NumberOfActuationsLift                                            | 0x0005 |
| * NumberOfActuationsTilt                                            | 0x0006 |
| * ConfigStatus                                                      | 0x0007 |
| * CurrentPositionLiftPercentage                                     | 0x0008 |
| * CurrentPositionTiltPercentage                                     | 0x0009 |
| * OperationalStatus                                                 | 0x000A |
| * TargetPositionLiftPercent100ths                                   | 0x000B |
| * TargetPositionTiltPercent100ths                                   | 0x000C |
| * EndProductType                                                    | 0x000D |
| * CurrentPositionLiftPercent100ths                                  | 0x000E |
| * CurrentPositionTiltPercent100ths                                  | 0x000F |
| * InstalledOpenLimitLift                                            | 0x0010 |
| * InstalledClosedLimitLift                                          | 0x0011 |
| * InstalledOpenLimitTilt                                            | 0x0012 |
| * InstalledClosedLimitTilt                                          | 0x0013 |
| * Mode                                                              | 0x0017 |
| * SafetyStatus                                                      | 0x001A |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command UpOrOpen
 */
class WindowCoveringUpOrOpen : public ClusterCommand {
public:
    WindowCoveringUpOrOpen()
        : ClusterCommand("up-or-open")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWindowCoveringClusterUpOrOpenParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster upOrOpenWithParams:params
                             completion:^(NSError * _Nullable error) {
                                 responsesNeeded--;
                                 if (error != nil) {
                                     mError = error;
                                     LogNSError("Error", error);
                                 }
                                 if (responsesNeeded == 0) {
                                     SetCommandExitStatus(mError);
                                 }
                             }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command DownOrClose
 */
class WindowCoveringDownOrClose : public ClusterCommand {
public:
    WindowCoveringDownOrClose()
        : ClusterCommand("down-or-close")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWindowCoveringClusterDownOrCloseParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster downOrCloseWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command StopMotion
 */
class WindowCoveringStopMotion : public ClusterCommand {
public:
    WindowCoveringStopMotion()
        : ClusterCommand("stop-motion")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWindowCoveringClusterStopMotionParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stopMotionWithParams:params
                               completion:^(NSError * _Nullable error) {
                                   responsesNeeded--;
                                   if (error != nil) {
                                       mError = error;
                                       LogNSError("Error", error);
                                   }
                                   if (responsesNeeded == 0) {
                                       SetCommandExitStatus(mError);
                                   }
                               }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command GoToLiftValue
 */
class WindowCoveringGoToLiftValue : public ClusterCommand {
public:
    WindowCoveringGoToLiftValue()
        : ClusterCommand("go-to-lift-value")
    {
        AddArgument("LiftValue", 0, UINT16_MAX, &mRequest.liftValue);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWindowCoveringClusterGoToLiftValueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.liftValue = [NSNumber numberWithUnsignedShort:mRequest.liftValue];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster goToLiftValueWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::WindowCovering::Commands::GoToLiftValue::Type mRequest;
};

/*
 * Command GoToLiftPercentage
 */
class WindowCoveringGoToLiftPercentage : public ClusterCommand {
public:
    WindowCoveringGoToLiftPercentage()
        : ClusterCommand("go-to-lift-percentage")
    {
        AddArgument("LiftPercent100thsValue", 0, UINT16_MAX, &mRequest.liftPercent100thsValue);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWindowCoveringClusterGoToLiftPercentageParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.liftPercent100thsValue = [NSNumber numberWithUnsignedShort:mRequest.liftPercent100thsValue];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster goToLiftPercentageWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::WindowCovering::Commands::GoToLiftPercentage::Type mRequest;
};

/*
 * Command GoToTiltValue
 */
class WindowCoveringGoToTiltValue : public ClusterCommand {
public:
    WindowCoveringGoToTiltValue()
        : ClusterCommand("go-to-tilt-value")
    {
        AddArgument("TiltValue", 0, UINT16_MAX, &mRequest.tiltValue);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) command (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWindowCoveringClusterGoToTiltValueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.tiltValue = [NSNumber numberWithUnsignedShort:mRequest.tiltValue];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster goToTiltValueWithParams:params
                                  completion:^(NSError * _Nullable error) {
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::WindowCovering::Commands::GoToTiltValue::Type mRequest;
};

/*
 * Command GoToTiltPercentage
 */
class WindowCoveringGoToTiltPercentage : public ClusterCommand {
public:
    WindowCoveringGoToTiltPercentage()
        : ClusterCommand("go-to-tilt-percentage")
    {
        AddArgument("TiltPercent100thsValue", 0, UINT16_MAX, &mRequest.tiltPercent100thsValue);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) command (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWindowCoveringClusterGoToTiltPercentageParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.tiltPercent100thsValue = [NSNumber numberWithUnsignedShort:mRequest.tiltPercent100thsValue];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster goToTiltPercentageWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::WindowCovering::Commands::GoToTiltPercentage::Type mRequest;
};

/*
 * Attribute Type
 */
class ReadWindowCoveringType : public ReadAttribute {
public:
    ReadWindowCoveringType()
        : ReadAttribute("type")
    {
    }

    ~ReadWindowCoveringType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.Type response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering Type read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringType : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringType()
        : SubscribeAttribute("type")
    {
    }

    ~SubscribeAttributeWindowCoveringType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.Type response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PhysicalClosedLimitLift
 */
class ReadWindowCoveringPhysicalClosedLimitLift : public ReadAttribute {
public:
    ReadWindowCoveringPhysicalClosedLimitLift()
        : ReadAttribute("physical-closed-limit-lift")
    {
    }

    ~ReadWindowCoveringPhysicalClosedLimitLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributePhysicalClosedLimitLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.PhysicalClosedLimitLift response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering PhysicalClosedLimitLift read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringPhysicalClosedLimitLift : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringPhysicalClosedLimitLift()
        : SubscribeAttribute("physical-closed-limit-lift")
    {
    }

    ~SubscribeAttributeWindowCoveringPhysicalClosedLimitLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhysicalClosedLimitLiftWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.PhysicalClosedLimitLift response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PhysicalClosedLimitTilt
 */
class ReadWindowCoveringPhysicalClosedLimitTilt : public ReadAttribute {
public:
    ReadWindowCoveringPhysicalClosedLimitTilt()
        : ReadAttribute("physical-closed-limit-tilt")
    {
    }

    ~ReadWindowCoveringPhysicalClosedLimitTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributePhysicalClosedLimitTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.PhysicalClosedLimitTilt response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering PhysicalClosedLimitTilt read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringPhysicalClosedLimitTilt : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringPhysicalClosedLimitTilt()
        : SubscribeAttribute("physical-closed-limit-tilt")
    {
    }

    ~SubscribeAttributeWindowCoveringPhysicalClosedLimitTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhysicalClosedLimitTiltWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.PhysicalClosedLimitTilt response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentPositionLift
 */
class ReadWindowCoveringCurrentPositionLift : public ReadAttribute {
public:
    ReadWindowCoveringCurrentPositionLift()
        : ReadAttribute("current-position-lift")
    {
    }

    ~ReadWindowCoveringCurrentPositionLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeCurrentPositionLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.CurrentPositionLift response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering CurrentPositionLift read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringCurrentPositionLift : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringCurrentPositionLift()
        : SubscribeAttribute("current-position-lift")
    {
    }

    ~SubscribeAttributeWindowCoveringCurrentPositionLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentPositionLiftWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionLift response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentPositionTilt
 */
class ReadWindowCoveringCurrentPositionTilt : public ReadAttribute {
public:
    ReadWindowCoveringCurrentPositionTilt()
        : ReadAttribute("current-position-tilt")
    {
    }

    ~ReadWindowCoveringCurrentPositionTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeCurrentPositionTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.CurrentPositionTilt response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering CurrentPositionTilt read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringCurrentPositionTilt : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringCurrentPositionTilt()
        : SubscribeAttribute("current-position-tilt")
    {
    }

    ~SubscribeAttributeWindowCoveringCurrentPositionTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentPositionTiltWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionTilt response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfActuationsLift
 */
class ReadWindowCoveringNumberOfActuationsLift : public ReadAttribute {
public:
    ReadWindowCoveringNumberOfActuationsLift()
        : ReadAttribute("number-of-actuations-lift")
    {
    }

    ~ReadWindowCoveringNumberOfActuationsLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeNumberOfActuationsLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.NumberOfActuationsLift response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering NumberOfActuationsLift read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringNumberOfActuationsLift : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringNumberOfActuationsLift()
        : SubscribeAttribute("number-of-actuations-lift")
    {
    }

    ~SubscribeAttributeWindowCoveringNumberOfActuationsLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfActuationsLiftWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.NumberOfActuationsLift response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfActuationsTilt
 */
class ReadWindowCoveringNumberOfActuationsTilt : public ReadAttribute {
public:
    ReadWindowCoveringNumberOfActuationsTilt()
        : ReadAttribute("number-of-actuations-tilt")
    {
    }

    ~ReadWindowCoveringNumberOfActuationsTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeNumberOfActuationsTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.NumberOfActuationsTilt response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering NumberOfActuationsTilt read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringNumberOfActuationsTilt : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringNumberOfActuationsTilt()
        : SubscribeAttribute("number-of-actuations-tilt")
    {
    }

    ~SubscribeAttributeWindowCoveringNumberOfActuationsTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfActuationsTiltWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.NumberOfActuationsTilt response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ConfigStatus
 */
class ReadWindowCoveringConfigStatus : public ReadAttribute {
public:
    ReadWindowCoveringConfigStatus()
        : ReadAttribute("config-status")
    {
    }

    ~ReadWindowCoveringConfigStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeConfigStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.ConfigStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering ConfigStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringConfigStatus : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringConfigStatus()
        : SubscribeAttribute("config-status")
    {
    }

    ~SubscribeAttributeWindowCoveringConfigStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeConfigStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.ConfigStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentPositionLiftPercentage
 */
class ReadWindowCoveringCurrentPositionLiftPercentage : public ReadAttribute {
public:
    ReadWindowCoveringCurrentPositionLiftPercentage()
        : ReadAttribute("current-position-lift-percentage")
    {
    }

    ~ReadWindowCoveringCurrentPositionLiftPercentage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeCurrentPositionLiftPercentageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.CurrentPositionLiftPercentage response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering CurrentPositionLiftPercentage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringCurrentPositionLiftPercentage : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringCurrentPositionLiftPercentage()
        : SubscribeAttribute("current-position-lift-percentage")
    {
    }

    ~SubscribeAttributeWindowCoveringCurrentPositionLiftPercentage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentPositionLiftPercentageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionLiftPercentage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentPositionTiltPercentage
 */
class ReadWindowCoveringCurrentPositionTiltPercentage : public ReadAttribute {
public:
    ReadWindowCoveringCurrentPositionTiltPercentage()
        : ReadAttribute("current-position-tilt-percentage")
    {
    }

    ~ReadWindowCoveringCurrentPositionTiltPercentage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeCurrentPositionTiltPercentageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.CurrentPositionTiltPercentage response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering CurrentPositionTiltPercentage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringCurrentPositionTiltPercentage : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringCurrentPositionTiltPercentage()
        : SubscribeAttribute("current-position-tilt-percentage")
    {
    }

    ~SubscribeAttributeWindowCoveringCurrentPositionTiltPercentage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentPositionTiltPercentageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionTiltPercentage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OperationalStatus
 */
class ReadWindowCoveringOperationalStatus : public ReadAttribute {
public:
    ReadWindowCoveringOperationalStatus()
        : ReadAttribute("operational-status")
    {
    }

    ~ReadWindowCoveringOperationalStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeOperationalStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.OperationalStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering OperationalStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringOperationalStatus : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringOperationalStatus()
        : SubscribeAttribute("operational-status")
    {
    }

    ~SubscribeAttributeWindowCoveringOperationalStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOperationalStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.OperationalStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TargetPositionLiftPercent100ths
 */
class ReadWindowCoveringTargetPositionLiftPercent100ths : public ReadAttribute {
public:
    ReadWindowCoveringTargetPositionLiftPercent100ths()
        : ReadAttribute("target-position-lift-percent100ths")
    {
    }

    ~ReadWindowCoveringTargetPositionLiftPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster
            readAttributeTargetPositionLiftPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.TargetPositionLiftPercent100ths response %@", [value description]);
                if (error != nil) {
                    LogNSError("WindowCovering TargetPositionLiftPercent100ths read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringTargetPositionLiftPercent100ths : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringTargetPositionLiftPercent100ths()
        : SubscribeAttribute("target-position-lift-percent100ths")
    {
    }

    ~SubscribeAttributeWindowCoveringTargetPositionLiftPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTargetPositionLiftPercent100thsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.TargetPositionLiftPercent100ths response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TargetPositionTiltPercent100ths
 */
class ReadWindowCoveringTargetPositionTiltPercent100ths : public ReadAttribute {
public:
    ReadWindowCoveringTargetPositionTiltPercent100ths()
        : ReadAttribute("target-position-tilt-percent100ths")
    {
    }

    ~ReadWindowCoveringTargetPositionTiltPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster
            readAttributeTargetPositionTiltPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.TargetPositionTiltPercent100ths response %@", [value description]);
                if (error != nil) {
                    LogNSError("WindowCovering TargetPositionTiltPercent100ths read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringTargetPositionTiltPercent100ths : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringTargetPositionTiltPercent100ths()
        : SubscribeAttribute("target-position-tilt-percent100ths")
    {
    }

    ~SubscribeAttributeWindowCoveringTargetPositionTiltPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTargetPositionTiltPercent100thsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.TargetPositionTiltPercent100ths response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EndProductType
 */
class ReadWindowCoveringEndProductType : public ReadAttribute {
public:
    ReadWindowCoveringEndProductType()
        : ReadAttribute("end-product-type")
    {
    }

    ~ReadWindowCoveringEndProductType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeEndProductTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.EndProductType response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering EndProductType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringEndProductType : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringEndProductType()
        : SubscribeAttribute("end-product-type")
    {
    }

    ~SubscribeAttributeWindowCoveringEndProductType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000000D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEndProductTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.EndProductType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentPositionLiftPercent100ths
 */
class ReadWindowCoveringCurrentPositionLiftPercent100ths : public ReadAttribute {
public:
    ReadWindowCoveringCurrentPositionLiftPercent100ths()
        : ReadAttribute("current-position-lift-percent100ths")
    {
    }

    ~ReadWindowCoveringCurrentPositionLiftPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster
            readAttributeCurrentPositionLiftPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionLiftPercent100ths response %@", [value description]);
                if (error != nil) {
                    LogNSError("WindowCovering CurrentPositionLiftPercent100ths read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringCurrentPositionLiftPercent100ths : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringCurrentPositionLiftPercent100ths()
        : SubscribeAttribute("current-position-lift-percent100ths")
    {
    }

    ~SubscribeAttributeWindowCoveringCurrentPositionLiftPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000000E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentPositionLiftPercent100thsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionLiftPercent100ths response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentPositionTiltPercent100ths
 */
class ReadWindowCoveringCurrentPositionTiltPercent100ths : public ReadAttribute {
public:
    ReadWindowCoveringCurrentPositionTiltPercent100ths()
        : ReadAttribute("current-position-tilt-percent100ths")
    {
    }

    ~ReadWindowCoveringCurrentPositionTiltPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster
            readAttributeCurrentPositionTiltPercent100thsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionTiltPercent100ths response %@", [value description]);
                if (error != nil) {
                    LogNSError("WindowCovering CurrentPositionTiltPercent100ths read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringCurrentPositionTiltPercent100ths : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringCurrentPositionTiltPercent100ths()
        : SubscribeAttribute("current-position-tilt-percent100ths")
    {
    }

    ~SubscribeAttributeWindowCoveringCurrentPositionTiltPercent100ths() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentPositionTiltPercent100thsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.CurrentPositionTiltPercent100ths response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstalledOpenLimitLift
 */
class ReadWindowCoveringInstalledOpenLimitLift : public ReadAttribute {
public:
    ReadWindowCoveringInstalledOpenLimitLift()
        : ReadAttribute("installed-open-limit-lift")
    {
    }

    ~ReadWindowCoveringInstalledOpenLimitLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeInstalledOpenLimitLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.InstalledOpenLimitLift response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering InstalledOpenLimitLift read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringInstalledOpenLimitLift : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringInstalledOpenLimitLift()
        : SubscribeAttribute("installed-open-limit-lift")
    {
    }

    ~SubscribeAttributeWindowCoveringInstalledOpenLimitLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstalledOpenLimitLiftWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.InstalledOpenLimitLift response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstalledClosedLimitLift
 */
class ReadWindowCoveringInstalledClosedLimitLift : public ReadAttribute {
public:
    ReadWindowCoveringInstalledClosedLimitLift()
        : ReadAttribute("installed-closed-limit-lift")
    {
    }

    ~ReadWindowCoveringInstalledClosedLimitLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeInstalledClosedLimitLiftWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.InstalledClosedLimitLift response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering InstalledClosedLimitLift read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringInstalledClosedLimitLift : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringInstalledClosedLimitLift()
        : SubscribeAttribute("installed-closed-limit-lift")
    {
    }

    ~SubscribeAttributeWindowCoveringInstalledClosedLimitLift() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstalledClosedLimitLiftWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.InstalledClosedLimitLift response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstalledOpenLimitTilt
 */
class ReadWindowCoveringInstalledOpenLimitTilt : public ReadAttribute {
public:
    ReadWindowCoveringInstalledOpenLimitTilt()
        : ReadAttribute("installed-open-limit-tilt")
    {
    }

    ~ReadWindowCoveringInstalledOpenLimitTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeInstalledOpenLimitTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.InstalledOpenLimitTilt response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering InstalledOpenLimitTilt read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringInstalledOpenLimitTilt : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringInstalledOpenLimitTilt()
        : SubscribeAttribute("installed-open-limit-tilt")
    {
    }

    ~SubscribeAttributeWindowCoveringInstalledOpenLimitTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstalledOpenLimitTiltWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.InstalledOpenLimitTilt response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstalledClosedLimitTilt
 */
class ReadWindowCoveringInstalledClosedLimitTilt : public ReadAttribute {
public:
    ReadWindowCoveringInstalledClosedLimitTilt()
        : ReadAttribute("installed-closed-limit-tilt")
    {
    }

    ~ReadWindowCoveringInstalledClosedLimitTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeInstalledClosedLimitTiltWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.InstalledClosedLimitTilt response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering InstalledClosedLimitTilt read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringInstalledClosedLimitTilt : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringInstalledClosedLimitTilt()
        : SubscribeAttribute("installed-closed-limit-tilt")
    {
    }

    ~SubscribeAttributeWindowCoveringInstalledClosedLimitTilt() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstalledClosedLimitTiltWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.InstalledClosedLimitTilt response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Mode
 */
class ReadWindowCoveringMode : public ReadAttribute {
public:
    ReadWindowCoveringMode()
        : ReadAttribute("mode")
    {
    }

    ~ReadWindowCoveringMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.Mode response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering Mode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteWindowCoveringMode : public WriteAttribute {
public:
    WriteWindowCoveringMode()
        : WriteAttribute("mode")
    {
        AddArgument("attr-name", "mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteWindowCoveringMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) WriteAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeModeWithValue:value
                                      params:params
                                  completion:^(NSError * _Nullable error) {
                                      if (error != nil) {
                                          LogNSError("WindowCovering Mode write Error", error);
                                      }
                                      SetCommandExitStatus(error);
                                  }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeWindowCoveringMode : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringMode()
        : SubscribeAttribute("mode")
    {
    }

    ~SubscribeAttributeWindowCoveringMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.Mode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SafetyStatus
 */
class ReadWindowCoveringSafetyStatus : public ReadAttribute {
public:
    ReadWindowCoveringSafetyStatus()
        : ReadAttribute("safety-status")
    {
    }

    ~ReadWindowCoveringSafetyStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeSafetyStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.SafetyStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering SafetyStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringSafetyStatus : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringSafetyStatus()
        : SubscribeAttribute("safety-status")
    {
    }

    ~SubscribeAttributeWindowCoveringSafetyStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSafetyStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.SafetyStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadWindowCoveringGeneratedCommandList : public ReadAttribute {
public:
    ReadWindowCoveringGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadWindowCoveringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeWindowCoveringGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadWindowCoveringAcceptedCommandList : public ReadAttribute {
public:
    ReadWindowCoveringAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadWindowCoveringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeWindowCoveringAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadWindowCoveringAttributeList : public ReadAttribute {
public:
    ReadWindowCoveringAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadWindowCoveringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeWindowCoveringAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadWindowCoveringFeatureMap : public ReadAttribute {
public:
    ReadWindowCoveringFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadWindowCoveringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeWindowCoveringFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadWindowCoveringClusterRevision : public ReadAttribute {
public:
    ReadWindowCoveringClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadWindowCoveringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeWindowCoveringClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster BarrierControl                                              | 0x0103 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * BarrierControlGoToPercent                                         |   0x00 |
| * BarrierControlStop                                                |   0x01 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * BarrierMovingState                                                | 0x0001 |
| * BarrierSafetyStatus                                               | 0x0002 |
| * BarrierCapabilities                                               | 0x0003 |
| * BarrierOpenEvents                                                 | 0x0004 |
| * BarrierCloseEvents                                                | 0x0005 |
| * BarrierCommandOpenEvents                                          | 0x0006 |
| * BarrierCommandCloseEvents                                         | 0x0007 |
| * BarrierOpenPeriod                                                 | 0x0008 |
| * BarrierClosePeriod                                                | 0x0009 |
| * BarrierPosition                                                   | 0x000A |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command BarrierControlGoToPercent
 */
class BarrierControlBarrierControlGoToPercent : public ClusterCommand {
public:
    BarrierControlBarrierControlGoToPercent()
        : ClusterCommand("barrier-control-go-to-percent")
    {
        AddArgument("PercentOpen", 0, UINT8_MAX, &mRequest.percentOpen);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRBarrierControlClusterBarrierControlGoToPercentParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.percentOpen = [NSNumber numberWithUnsignedChar:mRequest.percentOpen];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster barrierControlGoToPercentWithParams:params
                                              completion:^(NSError * _Nullable error) {
                                                  responsesNeeded--;
                                                  if (error != nil) {
                                                      mError = error;
                                                      LogNSError("Error", error);
                                                  }
                                                  if (responsesNeeded == 0) {
                                                      SetCommandExitStatus(mError);
                                                  }
                                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::BarrierControl::Commands::BarrierControlGoToPercent::Type mRequest;
};

/*
 * Command BarrierControlStop
 */
class BarrierControlBarrierControlStop : public ClusterCommand {
public:
    BarrierControlBarrierControlStop()
        : ClusterCommand("barrier-control-stop")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRBarrierControlClusterBarrierControlStopParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster barrierControlStopWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute BarrierMovingState
 */
class ReadBarrierControlBarrierMovingState : public ReadAttribute {
public:
    ReadBarrierControlBarrierMovingState()
        : ReadAttribute("barrier-moving-state")
    {
    }

    ~ReadBarrierControlBarrierMovingState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierMovingStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierMovingState response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierMovingState read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlBarrierMovingState : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierMovingState()
        : SubscribeAttribute("barrier-moving-state")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierMovingState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierMovingStateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierMovingState response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierSafetyStatus
 */
class ReadBarrierControlBarrierSafetyStatus : public ReadAttribute {
public:
    ReadBarrierControlBarrierSafetyStatus()
        : ReadAttribute("barrier-safety-status")
    {
    }

    ~ReadBarrierControlBarrierSafetyStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierSafetyStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierSafetyStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierSafetyStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlBarrierSafetyStatus : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierSafetyStatus()
        : SubscribeAttribute("barrier-safety-status")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierSafetyStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierSafetyStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierSafetyStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierCapabilities
 */
class ReadBarrierControlBarrierCapabilities : public ReadAttribute {
public:
    ReadBarrierControlBarrierCapabilities()
        : ReadAttribute("barrier-capabilities")
    {
    }

    ~ReadBarrierControlBarrierCapabilities() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierCapabilitiesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierCapabilities response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierCapabilities read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlBarrierCapabilities : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierCapabilities()
        : SubscribeAttribute("barrier-capabilities")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierCapabilities() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierCapabilitiesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierCapabilities response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierOpenEvents
 */
class ReadBarrierControlBarrierOpenEvents : public ReadAttribute {
public:
    ReadBarrierControlBarrierOpenEvents()
        : ReadAttribute("barrier-open-events")
    {
    }

    ~ReadBarrierControlBarrierOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierOpenEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierOpenEvents response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierOpenEvents read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBarrierControlBarrierOpenEvents : public WriteAttribute {
public:
    WriteBarrierControlBarrierOpenEvents()
        : WriteAttribute("barrier-open-events")
    {
        AddArgument("attr-name", "barrier-open-events");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBarrierControlBarrierOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) WriteAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeBarrierOpenEventsWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("BarrierControl BarrierOpenEvents write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeBarrierControlBarrierOpenEvents : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierOpenEvents()
        : SubscribeAttribute("barrier-open-events")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierOpenEventsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierOpenEvents response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierCloseEvents
 */
class ReadBarrierControlBarrierCloseEvents : public ReadAttribute {
public:
    ReadBarrierControlBarrierCloseEvents()
        : ReadAttribute("barrier-close-events")
    {
    }

    ~ReadBarrierControlBarrierCloseEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierCloseEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierCloseEvents response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierCloseEvents read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBarrierControlBarrierCloseEvents : public WriteAttribute {
public:
    WriteBarrierControlBarrierCloseEvents()
        : WriteAttribute("barrier-close-events")
    {
        AddArgument("attr-name", "barrier-close-events");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBarrierControlBarrierCloseEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) WriteAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeBarrierCloseEventsWithValue:value
                                                    params:params
                                                completion:^(NSError * _Nullable error) {
                                                    if (error != nil) {
                                                        LogNSError("BarrierControl BarrierCloseEvents write Error", error);
                                                    }
                                                    SetCommandExitStatus(error);
                                                }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeBarrierControlBarrierCloseEvents : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierCloseEvents()
        : SubscribeAttribute("barrier-close-events")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierCloseEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierCloseEventsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierCloseEvents response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierCommandOpenEvents
 */
class ReadBarrierControlBarrierCommandOpenEvents : public ReadAttribute {
public:
    ReadBarrierControlBarrierCommandOpenEvents()
        : ReadAttribute("barrier-command-open-events")
    {
    }

    ~ReadBarrierControlBarrierCommandOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierCommandOpenEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierCommandOpenEvents response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierCommandOpenEvents read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBarrierControlBarrierCommandOpenEvents : public WriteAttribute {
public:
    WriteBarrierControlBarrierCommandOpenEvents()
        : WriteAttribute("barrier-command-open-events")
    {
        AddArgument("attr-name", "barrier-command-open-events");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBarrierControlBarrierCommandOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) WriteAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeBarrierCommandOpenEventsWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("BarrierControl BarrierCommandOpenEvents write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeBarrierControlBarrierCommandOpenEvents : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierCommandOpenEvents()
        : SubscribeAttribute("barrier-command-open-events")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierCommandOpenEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierCommandOpenEventsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierCommandOpenEvents response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierCommandCloseEvents
 */
class ReadBarrierControlBarrierCommandCloseEvents : public ReadAttribute {
public:
    ReadBarrierControlBarrierCommandCloseEvents()
        : ReadAttribute("barrier-command-close-events")
    {
    }

    ~ReadBarrierControlBarrierCommandCloseEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierCommandCloseEventsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierCommandCloseEvents response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierCommandCloseEvents read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBarrierControlBarrierCommandCloseEvents : public WriteAttribute {
public:
    WriteBarrierControlBarrierCommandCloseEvents()
        : WriteAttribute("barrier-command-close-events")
    {
        AddArgument("attr-name", "barrier-command-close-events");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBarrierControlBarrierCommandCloseEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) WriteAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeBarrierCommandCloseEventsWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("BarrierControl BarrierCommandCloseEvents write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeBarrierControlBarrierCommandCloseEvents : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierCommandCloseEvents()
        : SubscribeAttribute("barrier-command-close-events")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierCommandCloseEvents() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierCommandCloseEventsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierCommandCloseEvents response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierOpenPeriod
 */
class ReadBarrierControlBarrierOpenPeriod : public ReadAttribute {
public:
    ReadBarrierControlBarrierOpenPeriod()
        : ReadAttribute("barrier-open-period")
    {
    }

    ~ReadBarrierControlBarrierOpenPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierOpenPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierOpenPeriod response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierOpenPeriod read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBarrierControlBarrierOpenPeriod : public WriteAttribute {
public:
    WriteBarrierControlBarrierOpenPeriod()
        : WriteAttribute("barrier-open-period")
    {
        AddArgument("attr-name", "barrier-open-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBarrierControlBarrierOpenPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) WriteAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeBarrierOpenPeriodWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("BarrierControl BarrierOpenPeriod write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeBarrierControlBarrierOpenPeriod : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierOpenPeriod()
        : SubscribeAttribute("barrier-open-period")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierOpenPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierOpenPeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierOpenPeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierClosePeriod
 */
class ReadBarrierControlBarrierClosePeriod : public ReadAttribute {
public:
    ReadBarrierControlBarrierClosePeriod()
        : ReadAttribute("barrier-close-period")
    {
    }

    ~ReadBarrierControlBarrierClosePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierClosePeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierClosePeriod response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierClosePeriod read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBarrierControlBarrierClosePeriod : public WriteAttribute {
public:
    WriteBarrierControlBarrierClosePeriod()
        : WriteAttribute("barrier-close-period")
    {
        AddArgument("attr-name", "barrier-close-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBarrierControlBarrierClosePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) WriteAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeBarrierClosePeriodWithValue:value
                                                    params:params
                                                completion:^(NSError * _Nullable error) {
                                                    if (error != nil) {
                                                        LogNSError("BarrierControl BarrierClosePeriod write Error", error);
                                                    }
                                                    SetCommandExitStatus(error);
                                                }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeBarrierControlBarrierClosePeriod : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierClosePeriod()
        : SubscribeAttribute("barrier-close-period")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierClosePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierClosePeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierClosePeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BarrierPosition
 */
class ReadBarrierControlBarrierPosition : public ReadAttribute {
public:
    ReadBarrierControlBarrierPosition()
        : ReadAttribute("barrier-position")
    {
    }

    ~ReadBarrierControlBarrierPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeBarrierPositionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.BarrierPosition response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl BarrierPosition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlBarrierPosition : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlBarrierPosition()
        : SubscribeAttribute("barrier-position")
    {
    }

    ~SubscribeAttributeBarrierControlBarrierPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBarrierPositionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.BarrierPosition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadBarrierControlGeneratedCommandList : public ReadAttribute {
public:
    ReadBarrierControlGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadBarrierControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeBarrierControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadBarrierControlAcceptedCommandList : public ReadAttribute {
public:
    ReadBarrierControlAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadBarrierControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeBarrierControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadBarrierControlAttributeList : public ReadAttribute {
public:
    ReadBarrierControlAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadBarrierControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeBarrierControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadBarrierControlFeatureMap : public ReadAttribute {
public:
    ReadBarrierControlFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadBarrierControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeBarrierControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadBarrierControlClusterRevision : public ReadAttribute {
public:
    ReadBarrierControlClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadBarrierControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeBarrierControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBarrierControl alloc] initWithDevice:device
                                                                          endpointID:@(endpointId)
                                                                               queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster PumpConfigurationAndControl                                 | 0x0200 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MaxPressure                                                       | 0x0000 |
| * MaxSpeed                                                          | 0x0001 |
| * MaxFlow                                                           | 0x0002 |
| * MinConstPressure                                                  | 0x0003 |
| * MaxConstPressure                                                  | 0x0004 |
| * MinCompPressure                                                   | 0x0005 |
| * MaxCompPressure                                                   | 0x0006 |
| * MinConstSpeed                                                     | 0x0007 |
| * MaxConstSpeed                                                     | 0x0008 |
| * MinConstFlow                                                      | 0x0009 |
| * MaxConstFlow                                                      | 0x000A |
| * MinConstTemp                                                      | 0x000B |
| * MaxConstTemp                                                      | 0x000C |
| * PumpStatus                                                        | 0x0010 |
| * EffectiveOperationMode                                            | 0x0011 |
| * EffectiveControlMode                                              | 0x0012 |
| * Capacity                                                          | 0x0013 |
| * Speed                                                             | 0x0014 |
| * LifetimeRunningHours                                              | 0x0015 |
| * Power                                                             | 0x0016 |
| * LifetimeEnergyConsumed                                            | 0x0017 |
| * OperationMode                                                     | 0x0020 |
| * ControlMode                                                       | 0x0021 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * SupplyVoltageLow                                                  | 0x0000 |
| * SupplyVoltageHigh                                                 | 0x0001 |
| * PowerMissingPhase                                                 | 0x0002 |
| * SystemPressureLow                                                 | 0x0003 |
| * SystemPressureHigh                                                | 0x0004 |
| * DryRunning                                                        | 0x0005 |
| * MotorTemperatureHigh                                              | 0x0006 |
| * PumpMotorFatalFailure                                             | 0x0007 |
| * ElectronicTemperatureHigh                                         | 0x0008 |
| * PumpBlocked                                                       | 0x0009 |
| * SensorFailure                                                     | 0x000A |
| * ElectronicNonFatalFailure                                         | 0x000B |
| * ElectronicFatalFailure                                            | 0x000C |
| * GeneralFault                                                      | 0x000D |
| * Leakage                                                           | 0x000E |
| * AirDetection                                                      | 0x000F |
| * TurbineOperation                                                  | 0x0010 |
\*----------------------------------------------------------------------------*/

/*
 * Attribute MaxPressure
 */
class ReadPumpConfigurationAndControlMaxPressure : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxPressure()
        : ReadAttribute("max-pressure")
    {
    }

    ~ReadPumpConfigurationAndControlMaxPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxPressure response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxPressure read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxPressure : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxPressure()
        : SubscribeAttribute("max-pressure")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxPressureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxPressure response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxSpeed
 */
class ReadPumpConfigurationAndControlMaxSpeed : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxSpeed()
        : ReadAttribute("max-speed")
    {
    }

    ~ReadPumpConfigurationAndControlMaxSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxSpeed response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxSpeed read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxSpeed : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxSpeed()
        : SubscribeAttribute("max-speed")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxSpeedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxSpeed response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxFlow
 */
class ReadPumpConfigurationAndControlMaxFlow : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxFlow()
        : ReadAttribute("max-flow")
    {
    }

    ~ReadPumpConfigurationAndControlMaxFlow() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxFlowWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxFlow response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxFlow read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxFlow : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxFlow()
        : SubscribeAttribute("max-flow")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxFlow() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxFlowWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxFlow response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinConstPressure
 */
class ReadPumpConfigurationAndControlMinConstPressure : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMinConstPressure()
        : ReadAttribute("min-const-pressure")
    {
    }

    ~ReadPumpConfigurationAndControlMinConstPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMinConstPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MinConstPressure response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MinConstPressure read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMinConstPressure : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMinConstPressure()
        : SubscribeAttribute("min-const-pressure")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMinConstPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinConstPressureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MinConstPressure response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxConstPressure
 */
class ReadPumpConfigurationAndControlMaxConstPressure : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxConstPressure()
        : ReadAttribute("max-const-pressure")
    {
    }

    ~ReadPumpConfigurationAndControlMaxConstPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxConstPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxConstPressure response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxConstPressure read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxConstPressure : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxConstPressure()
        : SubscribeAttribute("max-const-pressure")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxConstPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxConstPressureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxConstPressure response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinCompPressure
 */
class ReadPumpConfigurationAndControlMinCompPressure : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMinCompPressure()
        : ReadAttribute("min-comp-pressure")
    {
    }

    ~ReadPumpConfigurationAndControlMinCompPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMinCompPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MinCompPressure response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MinCompPressure read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMinCompPressure : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMinCompPressure()
        : SubscribeAttribute("min-comp-pressure")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMinCompPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinCompPressureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MinCompPressure response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxCompPressure
 */
class ReadPumpConfigurationAndControlMaxCompPressure : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxCompPressure()
        : ReadAttribute("max-comp-pressure")
    {
    }

    ~ReadPumpConfigurationAndControlMaxCompPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxCompPressureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxCompPressure response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxCompPressure read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxCompPressure : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxCompPressure()
        : SubscribeAttribute("max-comp-pressure")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxCompPressure() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxCompPressureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxCompPressure response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinConstSpeed
 */
class ReadPumpConfigurationAndControlMinConstSpeed : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMinConstSpeed()
        : ReadAttribute("min-const-speed")
    {
    }

    ~ReadPumpConfigurationAndControlMinConstSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMinConstSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MinConstSpeed response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MinConstSpeed read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMinConstSpeed : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMinConstSpeed()
        : SubscribeAttribute("min-const-speed")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMinConstSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinConstSpeedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MinConstSpeed response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxConstSpeed
 */
class ReadPumpConfigurationAndControlMaxConstSpeed : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxConstSpeed()
        : ReadAttribute("max-const-speed")
    {
    }

    ~ReadPumpConfigurationAndControlMaxConstSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxConstSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxConstSpeed response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxConstSpeed read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxConstSpeed : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxConstSpeed()
        : SubscribeAttribute("max-const-speed")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxConstSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxConstSpeedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxConstSpeed response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinConstFlow
 */
class ReadPumpConfigurationAndControlMinConstFlow : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMinConstFlow()
        : ReadAttribute("min-const-flow")
    {
    }

    ~ReadPumpConfigurationAndControlMinConstFlow() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMinConstFlowWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MinConstFlow response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MinConstFlow read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMinConstFlow : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMinConstFlow()
        : SubscribeAttribute("min-const-flow")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMinConstFlow() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinConstFlowWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MinConstFlow response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxConstFlow
 */
class ReadPumpConfigurationAndControlMaxConstFlow : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxConstFlow()
        : ReadAttribute("max-const-flow")
    {
    }

    ~ReadPumpConfigurationAndControlMaxConstFlow() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxConstFlowWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxConstFlow response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxConstFlow read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxConstFlow : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxConstFlow()
        : SubscribeAttribute("max-const-flow")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxConstFlow() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxConstFlowWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxConstFlow response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinConstTemp
 */
class ReadPumpConfigurationAndControlMinConstTemp : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMinConstTemp()
        : ReadAttribute("min-const-temp")
    {
    }

    ~ReadPumpConfigurationAndControlMinConstTemp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMinConstTempWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MinConstTemp response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MinConstTemp read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMinConstTemp : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMinConstTemp()
        : SubscribeAttribute("min-const-temp")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMinConstTemp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinConstTempWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MinConstTemp response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxConstTemp
 */
class ReadPumpConfigurationAndControlMaxConstTemp : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlMaxConstTemp()
        : ReadAttribute("max-const-temp")
    {
    }

    ~ReadPumpConfigurationAndControlMaxConstTemp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxConstTempWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.MaxConstTemp response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl MaxConstTemp read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlMaxConstTemp : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlMaxConstTemp()
        : SubscribeAttribute("max-const-temp")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlMaxConstTemp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxConstTempWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.MaxConstTemp response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PumpStatus
 */
class ReadPumpConfigurationAndControlPumpStatus : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlPumpStatus()
        : ReadAttribute("pump-status")
    {
    }

    ~ReadPumpConfigurationAndControlPumpStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributePumpStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.PumpStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl PumpStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlPumpStatus : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlPumpStatus()
        : SubscribeAttribute("pump-status")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlPumpStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePumpStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.PumpStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EffectiveOperationMode
 */
class ReadPumpConfigurationAndControlEffectiveOperationMode : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlEffectiveOperationMode()
        : ReadAttribute("effective-operation-mode")
    {
    }

    ~ReadPumpConfigurationAndControlEffectiveOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeEffectiveOperationModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.EffectiveOperationMode response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl EffectiveOperationMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlEffectiveOperationMode : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlEffectiveOperationMode()
        : SubscribeAttribute("effective-operation-mode")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlEffectiveOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEffectiveOperationModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.EffectiveOperationMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EffectiveControlMode
 */
class ReadPumpConfigurationAndControlEffectiveControlMode : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlEffectiveControlMode()
        : ReadAttribute("effective-control-mode")
    {
    }

    ~ReadPumpConfigurationAndControlEffectiveControlMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeEffectiveControlModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.EffectiveControlMode response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl EffectiveControlMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlEffectiveControlMode : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlEffectiveControlMode()
        : SubscribeAttribute("effective-control-mode")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlEffectiveControlMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEffectiveControlModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.EffectiveControlMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Capacity
 */
class ReadPumpConfigurationAndControlCapacity : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlCapacity()
        : ReadAttribute("capacity")
    {
    }

    ~ReadPumpConfigurationAndControlCapacity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeCapacityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.Capacity response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl Capacity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlCapacity : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlCapacity()
        : SubscribeAttribute("capacity")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlCapacity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCapacityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.Capacity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Speed
 */
class ReadPumpConfigurationAndControlSpeed : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlSpeed()
        : ReadAttribute("speed")
    {
    }

    ~ReadPumpConfigurationAndControlSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.Speed response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl Speed read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlSpeed : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlSpeed()
        : SubscribeAttribute("speed")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSpeedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.Speed response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LifetimeRunningHours
 */
class ReadPumpConfigurationAndControlLifetimeRunningHours : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlLifetimeRunningHours()
        : ReadAttribute("lifetime-running-hours")
    {
    }

    ~ReadPumpConfigurationAndControlLifetimeRunningHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeLifetimeRunningHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.LifetimeRunningHours response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl LifetimeRunningHours read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WritePumpConfigurationAndControlLifetimeRunningHours : public WriteAttribute {
public:
    WritePumpConfigurationAndControlLifetimeRunningHours()
        : WriteAttribute("lifetime-running-hours")
    {
        AddArgument("attr-name", "lifetime-running-hours");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WritePumpConfigurationAndControlLifetimeRunningHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) WriteAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeLifetimeRunningHoursWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("PumpConfigurationAndControl LifetimeRunningHours write Error",
                                                              error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributePumpConfigurationAndControlLifetimeRunningHours : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlLifetimeRunningHours()
        : SubscribeAttribute("lifetime-running-hours")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlLifetimeRunningHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLifetimeRunningHoursWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.LifetimeRunningHours response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Power
 */
class ReadPumpConfigurationAndControlPower : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlPower()
        : ReadAttribute("power")
    {
    }

    ~ReadPumpConfigurationAndControlPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.Power response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl Power read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlPower : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlPower()
        : SubscribeAttribute("power")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.Power response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LifetimeEnergyConsumed
 */
class ReadPumpConfigurationAndControlLifetimeEnergyConsumed : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlLifetimeEnergyConsumed()
        : ReadAttribute("lifetime-energy-consumed")
    {
    }

    ~ReadPumpConfigurationAndControlLifetimeEnergyConsumed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeLifetimeEnergyConsumedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.LifetimeEnergyConsumed response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl LifetimeEnergyConsumed read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WritePumpConfigurationAndControlLifetimeEnergyConsumed : public WriteAttribute {
public:
    WritePumpConfigurationAndControlLifetimeEnergyConsumed()
        : WriteAttribute("lifetime-energy-consumed")
    {
        AddArgument("attr-name", "lifetime-energy-consumed");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WritePumpConfigurationAndControlLifetimeEnergyConsumed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) WriteAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster
            writeAttributeLifetimeEnergyConsumedWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError(
                                                           "PumpConfigurationAndControl LifetimeEnergyConsumed write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributePumpConfigurationAndControlLifetimeEnergyConsumed : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlLifetimeEnergyConsumed()
        : SubscribeAttribute("lifetime-energy-consumed")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlLifetimeEnergyConsumed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLifetimeEnergyConsumedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.LifetimeEnergyConsumed response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OperationMode
 */
class ReadPumpConfigurationAndControlOperationMode : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlOperationMode()
        : ReadAttribute("operation-mode")
    {
    }

    ~ReadPumpConfigurationAndControlOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000020) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeOperationModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.OperationMode response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl OperationMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WritePumpConfigurationAndControlOperationMode : public WriteAttribute {
public:
    WritePumpConfigurationAndControlOperationMode()
        : WriteAttribute("operation-mode")
    {
        AddArgument("attr-name", "operation-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WritePumpConfigurationAndControlOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) WriteAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOperationModeWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("PumpConfigurationAndControl OperationMode write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributePumpConfigurationAndControlOperationMode : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlOperationMode()
        : SubscribeAttribute("operation-mode")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOperationModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.OperationMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ControlMode
 */
class ReadPumpConfigurationAndControlControlMode : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlControlMode()
        : ReadAttribute("control-mode")
    {
    }

    ~ReadPumpConfigurationAndControlControlMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x00000021) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeControlModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.ControlMode response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl ControlMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WritePumpConfigurationAndControlControlMode : public WriteAttribute {
public:
    WritePumpConfigurationAndControlControlMode()
        : WriteAttribute("control-mode")
    {
        AddArgument("attr-name", "control-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WritePumpConfigurationAndControlControlMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) WriteAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeControlModeWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("PumpConfigurationAndControl ControlMode write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributePumpConfigurationAndControlControlMode : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlControlMode()
        : SubscribeAttribute("control-mode")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlControlMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeControlModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.ControlMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadPumpConfigurationAndControlGeneratedCommandList : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadPumpConfigurationAndControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadPumpConfigurationAndControlAcceptedCommandList : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadPumpConfigurationAndControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadPumpConfigurationAndControlAttributeList : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadPumpConfigurationAndControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadPumpConfigurationAndControlFeatureMap : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadPumpConfigurationAndControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadPumpConfigurationAndControlClusterRevision : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadPumpConfigurationAndControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Thermostat                                                  | 0x0201 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * SetpointRaiseLower                                                |   0x00 |
| * SetWeeklySchedule                                                 |   0x01 |
| * GetWeeklySchedule                                                 |   0x02 |
| * ClearWeeklySchedule                                               |   0x03 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * LocalTemperature                                                  | 0x0000 |
| * OutdoorTemperature                                                | 0x0001 |
| * Occupancy                                                         | 0x0002 |
| * AbsMinHeatSetpointLimit                                           | 0x0003 |
| * AbsMaxHeatSetpointLimit                                           | 0x0004 |
| * AbsMinCoolSetpointLimit                                           | 0x0005 |
| * AbsMaxCoolSetpointLimit                                           | 0x0006 |
| * PICoolingDemand                                                   | 0x0007 |
| * PIHeatingDemand                                                   | 0x0008 |
| * HVACSystemTypeConfiguration                                       | 0x0009 |
| * LocalTemperatureCalibration                                       | 0x0010 |
| * OccupiedCoolingSetpoint                                           | 0x0011 |
| * OccupiedHeatingSetpoint                                           | 0x0012 |
| * UnoccupiedCoolingSetpoint                                         | 0x0013 |
| * UnoccupiedHeatingSetpoint                                         | 0x0014 |
| * MinHeatSetpointLimit                                              | 0x0015 |
| * MaxHeatSetpointLimit                                              | 0x0016 |
| * MinCoolSetpointLimit                                              | 0x0017 |
| * MaxCoolSetpointLimit                                              | 0x0018 |
| * MinSetpointDeadBand                                               | 0x0019 |
| * RemoteSensing                                                     | 0x001A |
| * ControlSequenceOfOperation                                        | 0x001B |
| * SystemMode                                                        | 0x001C |
| * ThermostatRunningMode                                             | 0x001E |
| * StartOfWeek                                                       | 0x0020 |
| * NumberOfWeeklyTransitions                                         | 0x0021 |
| * NumberOfDailyTransitions                                          | 0x0022 |
| * TemperatureSetpointHold                                           | 0x0023 |
| * TemperatureSetpointHoldDuration                                   | 0x0024 |
| * ThermostatProgrammingOperationMode                                | 0x0025 |
| * ThermostatRunningState                                            | 0x0029 |
| * SetpointChangeSource                                              | 0x0030 |
| * SetpointChangeAmount                                              | 0x0031 |
| * SetpointChangeSourceTimestamp                                     | 0x0032 |
| * OccupiedSetback                                                   | 0x0034 |
| * OccupiedSetbackMin                                                | 0x0035 |
| * OccupiedSetbackMax                                                | 0x0036 |
| * UnoccupiedSetback                                                 | 0x0037 |
| * UnoccupiedSetbackMin                                              | 0x0038 |
| * UnoccupiedSetbackMax                                              | 0x0039 |
| * EmergencyHeatDelta                                                | 0x003A |
| * ACType                                                            | 0x0040 |
| * ACCapacity                                                        | 0x0041 |
| * ACRefrigerantType                                                 | 0x0042 |
| * ACCompressorType                                                  | 0x0043 |
| * ACErrorCode                                                       | 0x0044 |
| * ACLouverPosition                                                  | 0x0045 |
| * ACCoilTemperature                                                 | 0x0046 |
| * ACCapacityformat                                                  | 0x0047 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command SetpointRaiseLower
 */
class ThermostatSetpointRaiseLower : public ClusterCommand {
public:
    ThermostatSetpointRaiseLower()
        : ClusterCommand("setpoint-raise-lower")
    {
        AddArgument("Mode", 0, UINT8_MAX, &mRequest.mode);
        AddArgument("Amount", INT8_MIN, INT8_MAX, &mRequest.amount);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRThermostatClusterSetpointRaiseLowerParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.mode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.mode)];
        params.amount = [NSNumber numberWithChar:mRequest.amount];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster setpointRaiseLowerWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Thermostat::Commands::SetpointRaiseLower::Type mRequest;
};

/*
 * Command SetWeeklySchedule
 */
class ThermostatSetWeeklySchedule : public ClusterCommand {
public:
    ThermostatSetWeeklySchedule()
        : ClusterCommand("set-weekly-schedule")
        , mComplex_Transitions(&mRequest.transitions)
    {
        AddArgument("NumberOfTransitionsForSequence", 0, UINT8_MAX, &mRequest.numberOfTransitionsForSequence);
        AddArgument("DayOfWeekForSequence", 0, UINT8_MAX, &mRequest.dayOfWeekForSequence);
        AddArgument("ModeForSequence", 0, UINT8_MAX, &mRequest.modeForSequence);
        AddArgument("Transitions", &mComplex_Transitions);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRThermostatClusterSetWeeklyScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.numberOfTransitionsForSequence = [NSNumber numberWithUnsignedChar:mRequest.numberOfTransitionsForSequence];
        params.dayOfWeekForSequence = [NSNumber numberWithUnsignedChar:mRequest.dayOfWeekForSequence.Raw()];
        params.modeForSequence = [NSNumber numberWithUnsignedChar:mRequest.modeForSequence.Raw()];
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.transitions) {
                MTRThermostatClusterThermostatScheduleTransition * newElement_0;
                newElement_0 = [MTRThermostatClusterThermostatScheduleTransition new];
                newElement_0.transitionTime = [NSNumber numberWithUnsignedShort:entry_0.transitionTime];
                if (entry_0.heatSetpoint.IsNull()) {
                    newElement_0.heatSetpoint = nil;
                } else {
                    newElement_0.heatSetpoint = [NSNumber numberWithShort:entry_0.heatSetpoint.Value()];
                }
                if (entry_0.coolSetpoint.IsNull()) {
                    newElement_0.coolSetpoint = nil;
                } else {
                    newElement_0.coolSetpoint = [NSNumber numberWithShort:entry_0.coolSetpoint.Value()];
                }
                [array_0 addObject:newElement_0];
            }
            params.transitions = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster setWeeklyScheduleWithParams:params
                                      completion:^(NSError * _Nullable error) {
                                          responsesNeeded--;
                                          if (error != nil) {
                                              mError = error;
                                              LogNSError("Error", error);
                                          }
                                          if (responsesNeeded == 0) {
                                              SetCommandExitStatus(mError);
                                          }
                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Thermostat::Commands::SetWeeklySchedule::Type mRequest;
    TypedComplexArgument<
        chip::app::DataModel::List<const chip::app::Clusters::Thermostat::Structs::ThermostatScheduleTransition::Type>>
        mComplex_Transitions;
};

/*
 * Command GetWeeklySchedule
 */
class ThermostatGetWeeklySchedule : public ClusterCommand {
public:
    ThermostatGetWeeklySchedule()
        : ClusterCommand("get-weekly-schedule")
    {
        AddArgument("DaysToReturn", 0, UINT8_MAX, &mRequest.daysToReturn);
        AddArgument("ModeToReturn", 0, UINT8_MAX, &mRequest.modeToReturn);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRThermostatClusterGetWeeklyScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.daysToReturn = [NSNumber numberWithUnsignedChar:mRequest.daysToReturn.Raw()];
        params.modeToReturn = [NSNumber numberWithUnsignedChar:mRequest.modeToReturn.Raw()];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getWeeklyScheduleWithParams:params
                                      completion:^(MTRThermostatClusterGetWeeklyScheduleResponseParams * _Nullable values,
                                          NSError * _Nullable error) {
                                          NSLog(@"Values: %@", values);
                                          responsesNeeded--;
                                          if (error != nil) {
                                              mError = error;
                                              LogNSError("Error", error);
                                          }
                                          if (responsesNeeded == 0) {
                                              SetCommandExitStatus(mError);
                                          }
                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Thermostat::Commands::GetWeeklySchedule::Type mRequest;
};

/*
 * Command ClearWeeklySchedule
 */
class ThermostatClearWeeklySchedule : public ClusterCommand {
public:
    ThermostatClearWeeklySchedule()
        : ClusterCommand("clear-weekly-schedule")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRThermostatClusterClearWeeklyScheduleParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster clearWeeklyScheduleWithParams:params
                                        completion:^(NSError * _Nullable error) {
                                            responsesNeeded--;
                                            if (error != nil) {
                                                mError = error;
                                                LogNSError("Error", error);
                                            }
                                            if (responsesNeeded == 0) {
                                                SetCommandExitStatus(mError);
                                            }
                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute LocalTemperature
 */
class ReadThermostatLocalTemperature : public ReadAttribute {
public:
    ReadThermostatLocalTemperature()
        : ReadAttribute("local-temperature")
    {
    }

    ~ReadThermostatLocalTemperature() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeLocalTemperatureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.LocalTemperature response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat LocalTemperature read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatLocalTemperature : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatLocalTemperature()
        : SubscribeAttribute("local-temperature")
    {
    }

    ~SubscribeAttributeThermostatLocalTemperature() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLocalTemperatureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.LocalTemperature response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OutdoorTemperature
 */
class ReadThermostatOutdoorTemperature : public ReadAttribute {
public:
    ReadThermostatOutdoorTemperature()
        : ReadAttribute("outdoor-temperature")
    {
    }

    ~ReadThermostatOutdoorTemperature() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOutdoorTemperatureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.OutdoorTemperature response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat OutdoorTemperature read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatOutdoorTemperature : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatOutdoorTemperature()
        : SubscribeAttribute("outdoor-temperature")
    {
    }

    ~SubscribeAttributeThermostatOutdoorTemperature() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOutdoorTemperatureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.OutdoorTemperature response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Occupancy
 */
class ReadThermostatOccupancy : public ReadAttribute {
public:
    ReadThermostatOccupancy()
        : ReadAttribute("occupancy")
    {
    }

    ~ReadThermostatOccupancy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOccupancyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.Occupancy response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat Occupancy read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatOccupancy : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatOccupancy()
        : SubscribeAttribute("occupancy")
    {
    }

    ~SubscribeAttributeThermostatOccupancy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupancyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.Occupancy response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AbsMinHeatSetpointLimit
 */
class ReadThermostatAbsMinHeatSetpointLimit : public ReadAttribute {
public:
    ReadThermostatAbsMinHeatSetpointLimit()
        : ReadAttribute("abs-min-heat-setpoint-limit")
    {
    }

    ~ReadThermostatAbsMinHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAbsMinHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.AbsMinHeatSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat AbsMinHeatSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatAbsMinHeatSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatAbsMinHeatSetpointLimit()
        : SubscribeAttribute("abs-min-heat-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatAbsMinHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAbsMinHeatSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.AbsMinHeatSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AbsMaxHeatSetpointLimit
 */
class ReadThermostatAbsMaxHeatSetpointLimit : public ReadAttribute {
public:
    ReadThermostatAbsMaxHeatSetpointLimit()
        : ReadAttribute("abs-max-heat-setpoint-limit")
    {
    }

    ~ReadThermostatAbsMaxHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAbsMaxHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.AbsMaxHeatSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat AbsMaxHeatSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatAbsMaxHeatSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatAbsMaxHeatSetpointLimit()
        : SubscribeAttribute("abs-max-heat-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatAbsMaxHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAbsMaxHeatSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.AbsMaxHeatSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AbsMinCoolSetpointLimit
 */
class ReadThermostatAbsMinCoolSetpointLimit : public ReadAttribute {
public:
    ReadThermostatAbsMinCoolSetpointLimit()
        : ReadAttribute("abs-min-cool-setpoint-limit")
    {
    }

    ~ReadThermostatAbsMinCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAbsMinCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.AbsMinCoolSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat AbsMinCoolSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatAbsMinCoolSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatAbsMinCoolSetpointLimit()
        : SubscribeAttribute("abs-min-cool-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatAbsMinCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAbsMinCoolSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.AbsMinCoolSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AbsMaxCoolSetpointLimit
 */
class ReadThermostatAbsMaxCoolSetpointLimit : public ReadAttribute {
public:
    ReadThermostatAbsMaxCoolSetpointLimit()
        : ReadAttribute("abs-max-cool-setpoint-limit")
    {
    }

    ~ReadThermostatAbsMaxCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAbsMaxCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.AbsMaxCoolSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat AbsMaxCoolSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatAbsMaxCoolSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatAbsMaxCoolSetpointLimit()
        : SubscribeAttribute("abs-max-cool-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatAbsMaxCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAbsMaxCoolSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.AbsMaxCoolSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PICoolingDemand
 */
class ReadThermostatPICoolingDemand : public ReadAttribute {
public:
    ReadThermostatPICoolingDemand()
        : ReadAttribute("picooling-demand")
    {
    }

    ~ReadThermostatPICoolingDemand() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributePICoolingDemandWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.PICoolingDemand response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat PICoolingDemand read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatPICoolingDemand : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatPICoolingDemand()
        : SubscribeAttribute("picooling-demand")
    {
    }

    ~SubscribeAttributeThermostatPICoolingDemand() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePICoolingDemandWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.PICoolingDemand response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PIHeatingDemand
 */
class ReadThermostatPIHeatingDemand : public ReadAttribute {
public:
    ReadThermostatPIHeatingDemand()
        : ReadAttribute("piheating-demand")
    {
    }

    ~ReadThermostatPIHeatingDemand() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributePIHeatingDemandWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.PIHeatingDemand response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat PIHeatingDemand read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatPIHeatingDemand : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatPIHeatingDemand()
        : SubscribeAttribute("piheating-demand")
    {
    }

    ~SubscribeAttributeThermostatPIHeatingDemand() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePIHeatingDemandWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.PIHeatingDemand response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute HVACSystemTypeConfiguration
 */
class ReadThermostatHVACSystemTypeConfiguration : public ReadAttribute {
public:
    ReadThermostatHVACSystemTypeConfiguration()
        : ReadAttribute("hvacsystem-type-configuration")
    {
    }

    ~ReadThermostatHVACSystemTypeConfiguration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeHVACSystemTypeConfigurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.HVACSystemTypeConfiguration response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat HVACSystemTypeConfiguration read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatHVACSystemTypeConfiguration : public WriteAttribute {
public:
    WriteThermostatHVACSystemTypeConfiguration()
        : WriteAttribute("hvacsystem-type-configuration")
    {
        AddArgument("attr-name", "hvacsystem-type-configuration");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatHVACSystemTypeConfiguration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster
            writeAttributeHVACSystemTypeConfigurationWithValue:value
                                                        params:params
                                                    completion:^(NSError * _Nullable error) {
                                                        if (error != nil) {
                                                            LogNSError("Thermostat HVACSystemTypeConfiguration write Error", error);
                                                        }
                                                        SetCommandExitStatus(error);
                                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatHVACSystemTypeConfiguration : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatHVACSystemTypeConfiguration()
        : SubscribeAttribute("hvacsystem-type-configuration")
    {
    }

    ~SubscribeAttributeThermostatHVACSystemTypeConfiguration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeHVACSystemTypeConfigurationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.HVACSystemTypeConfiguration response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LocalTemperatureCalibration
 */
class ReadThermostatLocalTemperatureCalibration : public ReadAttribute {
public:
    ReadThermostatLocalTemperatureCalibration()
        : ReadAttribute("local-temperature-calibration")
    {
    }

    ~ReadThermostatLocalTemperatureCalibration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeLocalTemperatureCalibrationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.LocalTemperatureCalibration response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat LocalTemperatureCalibration read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatLocalTemperatureCalibration : public WriteAttribute {
public:
    WriteThermostatLocalTemperatureCalibration()
        : WriteAttribute("local-temperature-calibration")
    {
        AddArgument("attr-name", "local-temperature-calibration");
        AddArgument("attr-value", INT8_MIN, INT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatLocalTemperatureCalibration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithChar:mValue];

        [cluster
            writeAttributeLocalTemperatureCalibrationWithValue:value
                                                        params:params
                                                    completion:^(NSError * _Nullable error) {
                                                        if (error != nil) {
                                                            LogNSError("Thermostat LocalTemperatureCalibration write Error", error);
                                                        }
                                                        SetCommandExitStatus(error);
                                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int8_t mValue;
};

class SubscribeAttributeThermostatLocalTemperatureCalibration : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatLocalTemperatureCalibration()
        : SubscribeAttribute("local-temperature-calibration")
    {
    }

    ~SubscribeAttributeThermostatLocalTemperatureCalibration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLocalTemperatureCalibrationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.LocalTemperatureCalibration response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OccupiedCoolingSetpoint
 */
class ReadThermostatOccupiedCoolingSetpoint : public ReadAttribute {
public:
    ReadThermostatOccupiedCoolingSetpoint()
        : ReadAttribute("occupied-cooling-setpoint")
    {
    }

    ~ReadThermostatOccupiedCoolingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOccupiedCoolingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.OccupiedCoolingSetpoint response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat OccupiedCoolingSetpoint read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatOccupiedCoolingSetpoint : public WriteAttribute {
public:
    WriteThermostatOccupiedCoolingSetpoint()
        : WriteAttribute("occupied-cooling-setpoint")
    {
        AddArgument("attr-name", "occupied-cooling-setpoint");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatOccupiedCoolingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeOccupiedCoolingSetpointWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("Thermostat OccupiedCoolingSetpoint write Error", error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatOccupiedCoolingSetpoint : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatOccupiedCoolingSetpoint()
        : SubscribeAttribute("occupied-cooling-setpoint")
    {
    }

    ~SubscribeAttributeThermostatOccupiedCoolingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupiedCoolingSetpointWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.OccupiedCoolingSetpoint response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OccupiedHeatingSetpoint
 */
class ReadThermostatOccupiedHeatingSetpoint : public ReadAttribute {
public:
    ReadThermostatOccupiedHeatingSetpoint()
        : ReadAttribute("occupied-heating-setpoint")
    {
    }

    ~ReadThermostatOccupiedHeatingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOccupiedHeatingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.OccupiedHeatingSetpoint response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat OccupiedHeatingSetpoint read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatOccupiedHeatingSetpoint : public WriteAttribute {
public:
    WriteThermostatOccupiedHeatingSetpoint()
        : WriteAttribute("occupied-heating-setpoint")
    {
        AddArgument("attr-name", "occupied-heating-setpoint");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatOccupiedHeatingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeOccupiedHeatingSetpointWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("Thermostat OccupiedHeatingSetpoint write Error", error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatOccupiedHeatingSetpoint : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatOccupiedHeatingSetpoint()
        : SubscribeAttribute("occupied-heating-setpoint")
    {
    }

    ~SubscribeAttributeThermostatOccupiedHeatingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupiedHeatingSetpointWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.OccupiedHeatingSetpoint response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UnoccupiedCoolingSetpoint
 */
class ReadThermostatUnoccupiedCoolingSetpoint : public ReadAttribute {
public:
    ReadThermostatUnoccupiedCoolingSetpoint()
        : ReadAttribute("unoccupied-cooling-setpoint")
    {
    }

    ~ReadThermostatUnoccupiedCoolingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeUnoccupiedCoolingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.UnoccupiedCoolingSetpoint response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat UnoccupiedCoolingSetpoint read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatUnoccupiedCoolingSetpoint : public WriteAttribute {
public:
    WriteThermostatUnoccupiedCoolingSetpoint()
        : WriteAttribute("unoccupied-cooling-setpoint")
    {
        AddArgument("attr-name", "unoccupied-cooling-setpoint");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatUnoccupiedCoolingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster
            writeAttributeUnoccupiedCoolingSetpointWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("Thermostat UnoccupiedCoolingSetpoint write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatUnoccupiedCoolingSetpoint : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUnoccupiedCoolingSetpoint()
        : SubscribeAttribute("unoccupied-cooling-setpoint")
    {
    }

    ~SubscribeAttributeThermostatUnoccupiedCoolingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUnoccupiedCoolingSetpointWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.UnoccupiedCoolingSetpoint response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UnoccupiedHeatingSetpoint
 */
class ReadThermostatUnoccupiedHeatingSetpoint : public ReadAttribute {
public:
    ReadThermostatUnoccupiedHeatingSetpoint()
        : ReadAttribute("unoccupied-heating-setpoint")
    {
    }

    ~ReadThermostatUnoccupiedHeatingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeUnoccupiedHeatingSetpointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.UnoccupiedHeatingSetpoint response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat UnoccupiedHeatingSetpoint read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatUnoccupiedHeatingSetpoint : public WriteAttribute {
public:
    WriteThermostatUnoccupiedHeatingSetpoint()
        : WriteAttribute("unoccupied-heating-setpoint")
    {
        AddArgument("attr-name", "unoccupied-heating-setpoint");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatUnoccupiedHeatingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster
            writeAttributeUnoccupiedHeatingSetpointWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("Thermostat UnoccupiedHeatingSetpoint write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatUnoccupiedHeatingSetpoint : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUnoccupiedHeatingSetpoint()
        : SubscribeAttribute("unoccupied-heating-setpoint")
    {
    }

    ~SubscribeAttributeThermostatUnoccupiedHeatingSetpoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUnoccupiedHeatingSetpointWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.UnoccupiedHeatingSetpoint response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinHeatSetpointLimit
 */
class ReadThermostatMinHeatSetpointLimit : public ReadAttribute {
public:
    ReadThermostatMinHeatSetpointLimit()
        : ReadAttribute("min-heat-setpoint-limit")
    {
    }

    ~ReadThermostatMinHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeMinHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.MinHeatSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat MinHeatSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatMinHeatSetpointLimit : public WriteAttribute {
public:
    WriteThermostatMinHeatSetpointLimit()
        : WriteAttribute("min-heat-setpoint-limit")
    {
        AddArgument("attr-name", "min-heat-setpoint-limit");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatMinHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeMinHeatSetpointLimitWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("Thermostat MinHeatSetpointLimit write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatMinHeatSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatMinHeatSetpointLimit()
        : SubscribeAttribute("min-heat-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatMinHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinHeatSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.MinHeatSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxHeatSetpointLimit
 */
class ReadThermostatMaxHeatSetpointLimit : public ReadAttribute {
public:
    ReadThermostatMaxHeatSetpointLimit()
        : ReadAttribute("max-heat-setpoint-limit")
    {
    }

    ~ReadThermostatMaxHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeMaxHeatSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.MaxHeatSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat MaxHeatSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatMaxHeatSetpointLimit : public WriteAttribute {
public:
    WriteThermostatMaxHeatSetpointLimit()
        : WriteAttribute("max-heat-setpoint-limit")
    {
        AddArgument("attr-name", "max-heat-setpoint-limit");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatMaxHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeMaxHeatSetpointLimitWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("Thermostat MaxHeatSetpointLimit write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatMaxHeatSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatMaxHeatSetpointLimit()
        : SubscribeAttribute("max-heat-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatMaxHeatSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxHeatSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.MaxHeatSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinCoolSetpointLimit
 */
class ReadThermostatMinCoolSetpointLimit : public ReadAttribute {
public:
    ReadThermostatMinCoolSetpointLimit()
        : ReadAttribute("min-cool-setpoint-limit")
    {
    }

    ~ReadThermostatMinCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeMinCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.MinCoolSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat MinCoolSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatMinCoolSetpointLimit : public WriteAttribute {
public:
    WriteThermostatMinCoolSetpointLimit()
        : WriteAttribute("min-cool-setpoint-limit")
    {
        AddArgument("attr-name", "min-cool-setpoint-limit");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatMinCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeMinCoolSetpointLimitWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("Thermostat MinCoolSetpointLimit write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatMinCoolSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatMinCoolSetpointLimit()
        : SubscribeAttribute("min-cool-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatMinCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinCoolSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.MinCoolSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxCoolSetpointLimit
 */
class ReadThermostatMaxCoolSetpointLimit : public ReadAttribute {
public:
    ReadThermostatMaxCoolSetpointLimit()
        : ReadAttribute("max-cool-setpoint-limit")
    {
    }

    ~ReadThermostatMaxCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000018) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeMaxCoolSetpointLimitWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.MaxCoolSetpointLimit response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat MaxCoolSetpointLimit read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatMaxCoolSetpointLimit : public WriteAttribute {
public:
    WriteThermostatMaxCoolSetpointLimit()
        : WriteAttribute("max-cool-setpoint-limit")
    {
        AddArgument("attr-name", "max-cool-setpoint-limit");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatMaxCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeMaxCoolSetpointLimitWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("Thermostat MaxCoolSetpointLimit write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeThermostatMaxCoolSetpointLimit : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatMaxCoolSetpointLimit()
        : SubscribeAttribute("max-cool-setpoint-limit")
    {
    }

    ~SubscribeAttributeThermostatMaxCoolSetpointLimit() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxCoolSetpointLimitWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.MaxCoolSetpointLimit response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinSetpointDeadBand
 */
class ReadThermostatMinSetpointDeadBand : public ReadAttribute {
public:
    ReadThermostatMinSetpointDeadBand()
        : ReadAttribute("min-setpoint-dead-band")
    {
    }

    ~ReadThermostatMinSetpointDeadBand() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000019) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeMinSetpointDeadBandWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.MinSetpointDeadBand response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat MinSetpointDeadBand read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatMinSetpointDeadBand : public WriteAttribute {
public:
    WriteThermostatMinSetpointDeadBand()
        : WriteAttribute("min-setpoint-dead-band")
    {
        AddArgument("attr-name", "min-setpoint-dead-band");
        AddArgument("attr-value", INT8_MIN, INT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatMinSetpointDeadBand() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithChar:mValue];

        [cluster writeAttributeMinSetpointDeadBandWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("Thermostat MinSetpointDeadBand write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    int8_t mValue;
};

class SubscribeAttributeThermostatMinSetpointDeadBand : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatMinSetpointDeadBand()
        : SubscribeAttribute("min-setpoint-dead-band")
    {
    }

    ~SubscribeAttributeThermostatMinSetpointDeadBand() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinSetpointDeadBandWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.MinSetpointDeadBand response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RemoteSensing
 */
class ReadThermostatRemoteSensing : public ReadAttribute {
public:
    ReadThermostatRemoteSensing()
        : ReadAttribute("remote-sensing")
    {
    }

    ~ReadThermostatRemoteSensing() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeRemoteSensingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.RemoteSensing response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat RemoteSensing read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatRemoteSensing : public WriteAttribute {
public:
    WriteThermostatRemoteSensing()
        : WriteAttribute("remote-sensing")
    {
        AddArgument("attr-name", "remote-sensing");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatRemoteSensing() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeRemoteSensingWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("Thermostat RemoteSensing write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatRemoteSensing : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatRemoteSensing()
        : SubscribeAttribute("remote-sensing")
    {
    }

    ~SubscribeAttributeThermostatRemoteSensing() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRemoteSensingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.RemoteSensing response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ControlSequenceOfOperation
 */
class ReadThermostatControlSequenceOfOperation : public ReadAttribute {
public:
    ReadThermostatControlSequenceOfOperation()
        : ReadAttribute("control-sequence-of-operation")
    {
    }

    ~ReadThermostatControlSequenceOfOperation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000001B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeControlSequenceOfOperationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ControlSequenceOfOperation response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ControlSequenceOfOperation read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatControlSequenceOfOperation : public WriteAttribute {
public:
    WriteThermostatControlSequenceOfOperation()
        : WriteAttribute("control-sequence-of-operation")
    {
        AddArgument("attr-name", "control-sequence-of-operation");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatControlSequenceOfOperation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster
            writeAttributeControlSequenceOfOperationWithValue:value
                                                       params:params
                                                   completion:^(NSError * _Nullable error) {
                                                       if (error != nil) {
                                                           LogNSError("Thermostat ControlSequenceOfOperation write Error", error);
                                                       }
                                                       SetCommandExitStatus(error);
                                                   }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatControlSequenceOfOperation : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatControlSequenceOfOperation()
        : SubscribeAttribute("control-sequence-of-operation")
    {
    }

    ~SubscribeAttributeThermostatControlSequenceOfOperation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeControlSequenceOfOperationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ControlSequenceOfOperation response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SystemMode
 */
class ReadThermostatSystemMode : public ReadAttribute {
public:
    ReadThermostatSystemMode()
        : ReadAttribute("system-mode")
    {
    }

    ~ReadThermostatSystemMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000001C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSystemModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.SystemMode response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat SystemMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatSystemMode : public WriteAttribute {
public:
    WriteThermostatSystemMode()
        : WriteAttribute("system-mode")
    {
        AddArgument("attr-name", "system-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatSystemMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeSystemModeWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("Thermostat SystemMode write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatSystemMode : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatSystemMode()
        : SubscribeAttribute("system-mode")
    {
    }

    ~SubscribeAttributeThermostatSystemMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSystemModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.SystemMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ThermostatRunningMode
 */
class ReadThermostatThermostatRunningMode : public ReadAttribute {
public:
    ReadThermostatThermostatRunningMode()
        : ReadAttribute("thermostat-running-mode")
    {
    }

    ~ReadThermostatThermostatRunningMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000001E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeThermostatRunningModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ThermostatRunningMode response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ThermostatRunningMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatThermostatRunningMode : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatThermostatRunningMode()
        : SubscribeAttribute("thermostat-running-mode")
    {
    }

    ~SubscribeAttributeThermostatThermostatRunningMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000001E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeThermostatRunningModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ThermostatRunningMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StartOfWeek
 */
class ReadThermostatStartOfWeek : public ReadAttribute {
public:
    ReadThermostatStartOfWeek()
        : ReadAttribute("start-of-week")
    {
    }

    ~ReadThermostatStartOfWeek() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000020) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeStartOfWeekWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.StartOfWeek response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat StartOfWeek read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatStartOfWeek : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatStartOfWeek()
        : SubscribeAttribute("start-of-week")
    {
    }

    ~SubscribeAttributeThermostatStartOfWeek() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStartOfWeekWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.StartOfWeek response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfWeeklyTransitions
 */
class ReadThermostatNumberOfWeeklyTransitions : public ReadAttribute {
public:
    ReadThermostatNumberOfWeeklyTransitions()
        : ReadAttribute("number-of-weekly-transitions")
    {
    }

    ~ReadThermostatNumberOfWeeklyTransitions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000021) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeNumberOfWeeklyTransitionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.NumberOfWeeklyTransitions response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat NumberOfWeeklyTransitions read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatNumberOfWeeklyTransitions : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatNumberOfWeeklyTransitions()
        : SubscribeAttribute("number-of-weekly-transitions")
    {
    }

    ~SubscribeAttributeThermostatNumberOfWeeklyTransitions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfWeeklyTransitionsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.NumberOfWeeklyTransitions response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfDailyTransitions
 */
class ReadThermostatNumberOfDailyTransitions : public ReadAttribute {
public:
    ReadThermostatNumberOfDailyTransitions()
        : ReadAttribute("number-of-daily-transitions")
    {
    }

    ~ReadThermostatNumberOfDailyTransitions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000022) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeNumberOfDailyTransitionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.NumberOfDailyTransitions response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat NumberOfDailyTransitions read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatNumberOfDailyTransitions : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatNumberOfDailyTransitions()
        : SubscribeAttribute("number-of-daily-transitions")
    {
    }

    ~SubscribeAttributeThermostatNumberOfDailyTransitions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfDailyTransitionsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.NumberOfDailyTransitions response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TemperatureSetpointHold
 */
class ReadThermostatTemperatureSetpointHold : public ReadAttribute {
public:
    ReadThermostatTemperatureSetpointHold()
        : ReadAttribute("temperature-setpoint-hold")
    {
    }

    ~ReadThermostatTemperatureSetpointHold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000023) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeTemperatureSetpointHoldWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.TemperatureSetpointHold response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat TemperatureSetpointHold read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatTemperatureSetpointHold : public WriteAttribute {
public:
    WriteThermostatTemperatureSetpointHold()
        : WriteAttribute("temperature-setpoint-hold")
    {
        AddArgument("attr-name", "temperature-setpoint-hold");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatTemperatureSetpointHold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000023) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeTemperatureSetpointHoldWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("Thermostat TemperatureSetpointHold write Error", error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatTemperatureSetpointHold : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatTemperatureSetpointHold()
        : SubscribeAttribute("temperature-setpoint-hold")
    {
    }

    ~SubscribeAttributeThermostatTemperatureSetpointHold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000023) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTemperatureSetpointHoldWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.TemperatureSetpointHold response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TemperatureSetpointHoldDuration
 */
class ReadThermostatTemperatureSetpointHoldDuration : public ReadAttribute {
public:
    ReadThermostatTemperatureSetpointHoldDuration()
        : ReadAttribute("temperature-setpoint-hold-duration")
    {
    }

    ~ReadThermostatTemperatureSetpointHoldDuration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000024) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster
            readAttributeTemperatureSetpointHoldDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.TemperatureSetpointHoldDuration response %@", [value description]);
                if (error != nil) {
                    LogNSError("Thermostat TemperatureSetpointHoldDuration read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatTemperatureSetpointHoldDuration : public WriteAttribute {
public:
    WriteThermostatTemperatureSetpointHoldDuration()
        : WriteAttribute("temperature-setpoint-hold-duration")
    {
        AddArgument("attr-name", "temperature-setpoint-hold-duration");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatTemperatureSetpointHoldDuration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeTemperatureSetpointHoldDurationWithValue:value
                                                            params:params
                                                        completion:^(NSError * _Nullable error) {
                                                            if (error != nil) {
                                                                LogNSError("Thermostat TemperatureSetpointHoldDuration write Error",
                                                                    error);
                                                            }
                                                            SetCommandExitStatus(error);
                                                        }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeThermostatTemperatureSetpointHoldDuration : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatTemperatureSetpointHoldDuration()
        : SubscribeAttribute("temperature-setpoint-hold-duration")
    {
    }

    ~SubscribeAttributeThermostatTemperatureSetpointHoldDuration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTemperatureSetpointHoldDurationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.TemperatureSetpointHoldDuration response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ThermostatProgrammingOperationMode
 */
class ReadThermostatThermostatProgrammingOperationMode : public ReadAttribute {
public:
    ReadThermostatThermostatProgrammingOperationMode()
        : ReadAttribute("thermostat-programming-operation-mode")
    {
    }

    ~ReadThermostatThermostatProgrammingOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000025) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster
            readAttributeThermostatProgrammingOperationModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ThermostatProgrammingOperationMode response %@", [value description]);
                if (error != nil) {
                    LogNSError("Thermostat ThermostatProgrammingOperationMode read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatThermostatProgrammingOperationMode : public WriteAttribute {
public:
    WriteThermostatThermostatProgrammingOperationMode()
        : WriteAttribute("thermostat-programming-operation-mode")
    {
        AddArgument("attr-name", "thermostat-programming-operation-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatThermostatProgrammingOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster
            writeAttributeThermostatProgrammingOperationModeWithValue:value
                                                               params:params
                                                           completion:^(NSError * _Nullable error) {
                                                               if (error != nil) {
                                                                   LogNSError(
                                                                       "Thermostat ThermostatProgrammingOperationMode write Error",
                                                                       error);
                                                               }
                                                               SetCommandExitStatus(error);
                                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatThermostatProgrammingOperationMode : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatThermostatProgrammingOperationMode()
        : SubscribeAttribute("thermostat-programming-operation-mode")
    {
    }

    ~SubscribeAttributeThermostatThermostatProgrammingOperationMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeThermostatProgrammingOperationModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ThermostatProgrammingOperationMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ThermostatRunningState
 */
class ReadThermostatThermostatRunningState : public ReadAttribute {
public:
    ReadThermostatThermostatRunningState()
        : ReadAttribute("thermostat-running-state")
    {
    }

    ~ReadThermostatThermostatRunningState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000029) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeThermostatRunningStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ThermostatRunningState response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ThermostatRunningState read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatThermostatRunningState : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatThermostatRunningState()
        : SubscribeAttribute("thermostat-running-state")
    {
    }

    ~SubscribeAttributeThermostatThermostatRunningState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeThermostatRunningStateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ThermostatRunningState response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SetpointChangeSource
 */
class ReadThermostatSetpointChangeSource : public ReadAttribute {
public:
    ReadThermostatSetpointChangeSource()
        : ReadAttribute("setpoint-change-source")
    {
    }

    ~ReadThermostatSetpointChangeSource() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000030) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSetpointChangeSourceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.SetpointChangeSource response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat SetpointChangeSource read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatSetpointChangeSource : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatSetpointChangeSource()
        : SubscribeAttribute("setpoint-change-source")
    {
    }

    ~SubscribeAttributeThermostatSetpointChangeSource() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSetpointChangeSourceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.SetpointChangeSource response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SetpointChangeAmount
 */
class ReadThermostatSetpointChangeAmount : public ReadAttribute {
public:
    ReadThermostatSetpointChangeAmount()
        : ReadAttribute("setpoint-change-amount")
    {
    }

    ~ReadThermostatSetpointChangeAmount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000031) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSetpointChangeAmountWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.SetpointChangeAmount response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat SetpointChangeAmount read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatSetpointChangeAmount : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatSetpointChangeAmount()
        : SubscribeAttribute("setpoint-change-amount")
    {
    }

    ~SubscribeAttributeThermostatSetpointChangeAmount() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSetpointChangeAmountWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.SetpointChangeAmount response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SetpointChangeSourceTimestamp
 */
class ReadThermostatSetpointChangeSourceTimestamp : public ReadAttribute {
public:
    ReadThermostatSetpointChangeSourceTimestamp()
        : ReadAttribute("setpoint-change-source-timestamp")
    {
    }

    ~ReadThermostatSetpointChangeSourceTimestamp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000032) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSetpointChangeSourceTimestampWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.SetpointChangeSourceTimestamp response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat SetpointChangeSourceTimestamp read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatSetpointChangeSourceTimestamp : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatSetpointChangeSourceTimestamp()
        : SubscribeAttribute("setpoint-change-source-timestamp")
    {
    }

    ~SubscribeAttributeThermostatSetpointChangeSourceTimestamp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSetpointChangeSourceTimestampWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.SetpointChangeSourceTimestamp response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OccupiedSetback
 */
class ReadThermostatOccupiedSetback : public ReadAttribute {
public:
    ReadThermostatOccupiedSetback()
        : ReadAttribute("occupied-setback")
    {
    }

    ~ReadThermostatOccupiedSetback() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000034) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOccupiedSetbackWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.OccupiedSetback response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat OccupiedSetback read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatOccupiedSetback : public WriteAttribute {
public:
    WriteThermostatOccupiedSetback()
        : WriteAttribute("occupied-setback")
    {
        AddArgument("attr-name", "occupied-setback");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatOccupiedSetback() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000034) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOccupiedSetbackWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("Thermostat OccupiedSetback write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatOccupiedSetback : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatOccupiedSetback()
        : SubscribeAttribute("occupied-setback")
    {
    }

    ~SubscribeAttributeThermostatOccupiedSetback() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000034) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupiedSetbackWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.OccupiedSetback response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OccupiedSetbackMin
 */
class ReadThermostatOccupiedSetbackMin : public ReadAttribute {
public:
    ReadThermostatOccupiedSetbackMin()
        : ReadAttribute("occupied-setback-min")
    {
    }

    ~ReadThermostatOccupiedSetbackMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000035) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOccupiedSetbackMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.OccupiedSetbackMin response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat OccupiedSetbackMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatOccupiedSetbackMin : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatOccupiedSetbackMin()
        : SubscribeAttribute("occupied-setback-min")
    {
    }

    ~SubscribeAttributeThermostatOccupiedSetbackMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000035) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupiedSetbackMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.OccupiedSetbackMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OccupiedSetbackMax
 */
class ReadThermostatOccupiedSetbackMax : public ReadAttribute {
public:
    ReadThermostatOccupiedSetbackMax()
        : ReadAttribute("occupied-setback-max")
    {
    }

    ~ReadThermostatOccupiedSetbackMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000036) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeOccupiedSetbackMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.OccupiedSetbackMax response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat OccupiedSetbackMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatOccupiedSetbackMax : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatOccupiedSetbackMax()
        : SubscribeAttribute("occupied-setback-max")
    {
    }

    ~SubscribeAttributeThermostatOccupiedSetbackMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000036) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupiedSetbackMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.OccupiedSetbackMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UnoccupiedSetback
 */
class ReadThermostatUnoccupiedSetback : public ReadAttribute {
public:
    ReadThermostatUnoccupiedSetback()
        : ReadAttribute("unoccupied-setback")
    {
    }

    ~ReadThermostatUnoccupiedSetback() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000037) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeUnoccupiedSetbackWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.UnoccupiedSetback response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat UnoccupiedSetback read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatUnoccupiedSetback : public WriteAttribute {
public:
    WriteThermostatUnoccupiedSetback()
        : WriteAttribute("unoccupied-setback")
    {
        AddArgument("attr-name", "unoccupied-setback");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatUnoccupiedSetback() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000037) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeUnoccupiedSetbackWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("Thermostat UnoccupiedSetback write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatUnoccupiedSetback : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUnoccupiedSetback()
        : SubscribeAttribute("unoccupied-setback")
    {
    }

    ~SubscribeAttributeThermostatUnoccupiedSetback() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000037) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUnoccupiedSetbackWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.UnoccupiedSetback response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UnoccupiedSetbackMin
 */
class ReadThermostatUnoccupiedSetbackMin : public ReadAttribute {
public:
    ReadThermostatUnoccupiedSetbackMin()
        : ReadAttribute("unoccupied-setback-min")
    {
    }

    ~ReadThermostatUnoccupiedSetbackMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000038) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeUnoccupiedSetbackMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.UnoccupiedSetbackMin response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat UnoccupiedSetbackMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUnoccupiedSetbackMin : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUnoccupiedSetbackMin()
        : SubscribeAttribute("unoccupied-setback-min")
    {
    }

    ~SubscribeAttributeThermostatUnoccupiedSetbackMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000038) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUnoccupiedSetbackMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.UnoccupiedSetbackMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UnoccupiedSetbackMax
 */
class ReadThermostatUnoccupiedSetbackMax : public ReadAttribute {
public:
    ReadThermostatUnoccupiedSetbackMax()
        : ReadAttribute("unoccupied-setback-max")
    {
    }

    ~ReadThermostatUnoccupiedSetbackMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000039) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeUnoccupiedSetbackMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.UnoccupiedSetbackMax response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat UnoccupiedSetbackMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUnoccupiedSetbackMax : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUnoccupiedSetbackMax()
        : SubscribeAttribute("unoccupied-setback-max")
    {
    }

    ~SubscribeAttributeThermostatUnoccupiedSetbackMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000039) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUnoccupiedSetbackMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.UnoccupiedSetbackMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EmergencyHeatDelta
 */
class ReadThermostatEmergencyHeatDelta : public ReadAttribute {
public:
    ReadThermostatEmergencyHeatDelta()
        : ReadAttribute("emergency-heat-delta")
    {
    }

    ~ReadThermostatEmergencyHeatDelta() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000003A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeEmergencyHeatDeltaWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.EmergencyHeatDelta response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat EmergencyHeatDelta read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatEmergencyHeatDelta : public WriteAttribute {
public:
    WriteThermostatEmergencyHeatDelta()
        : WriteAttribute("emergency-heat-delta")
    {
        AddArgument("attr-name", "emergency-heat-delta");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatEmergencyHeatDelta() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x0000003A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeEmergencyHeatDeltaWithValue:value
                                                    params:params
                                                completion:^(NSError * _Nullable error) {
                                                    if (error != nil) {
                                                        LogNSError("Thermostat EmergencyHeatDelta write Error", error);
                                                    }
                                                    SetCommandExitStatus(error);
                                                }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatEmergencyHeatDelta : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatEmergencyHeatDelta()
        : SubscribeAttribute("emergency-heat-delta")
    {
    }

    ~SubscribeAttributeThermostatEmergencyHeatDelta() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000003A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEmergencyHeatDeltaWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.EmergencyHeatDelta response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACType
 */
class ReadThermostatACType : public ReadAttribute {
public:
    ReadThermostatACType()
        : ReadAttribute("actype")
    {
    }

    ~ReadThermostatACType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000040) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACType response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatACType : public WriteAttribute {
public:
    WriteThermostatACType()
        : WriteAttribute("actype")
    {
        AddArgument("attr-name", "actype");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatACType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000040) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeACTypeWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("Thermostat ACType write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatACType : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACType()
        : SubscribeAttribute("actype")
    {
    }

    ~SubscribeAttributeThermostatACType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000040) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACCapacity
 */
class ReadThermostatACCapacity : public ReadAttribute {
public:
    ReadThermostatACCapacity()
        : ReadAttribute("accapacity")
    {
    }

    ~ReadThermostatACCapacity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000041) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACCapacityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACCapacity response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACCapacity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatACCapacity : public WriteAttribute {
public:
    WriteThermostatACCapacity()
        : WriteAttribute("accapacity")
    {
        AddArgument("attr-name", "accapacity");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatACCapacity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000041) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeACCapacityWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("Thermostat ACCapacity write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeThermostatACCapacity : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACCapacity()
        : SubscribeAttribute("accapacity")
    {
    }

    ~SubscribeAttributeThermostatACCapacity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000041) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACCapacityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACCapacity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACRefrigerantType
 */
class ReadThermostatACRefrigerantType : public ReadAttribute {
public:
    ReadThermostatACRefrigerantType()
        : ReadAttribute("acrefrigerant-type")
    {
    }

    ~ReadThermostatACRefrigerantType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000042) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACRefrigerantTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACRefrigerantType response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACRefrigerantType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatACRefrigerantType : public WriteAttribute {
public:
    WriteThermostatACRefrigerantType()
        : WriteAttribute("acrefrigerant-type")
    {
        AddArgument("attr-name", "acrefrigerant-type");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatACRefrigerantType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000042) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeACRefrigerantTypeWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("Thermostat ACRefrigerantType write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatACRefrigerantType : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACRefrigerantType()
        : SubscribeAttribute("acrefrigerant-type")
    {
    }

    ~SubscribeAttributeThermostatACRefrigerantType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000042) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACRefrigerantTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACRefrigerantType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACCompressorType
 */
class ReadThermostatACCompressorType : public ReadAttribute {
public:
    ReadThermostatACCompressorType()
        : ReadAttribute("accompressor-type")
    {
    }

    ~ReadThermostatACCompressorType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000043) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACCompressorTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACCompressorType response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACCompressorType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatACCompressorType : public WriteAttribute {
public:
    WriteThermostatACCompressorType()
        : WriteAttribute("accompressor-type")
    {
        AddArgument("attr-name", "accompressor-type");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatACCompressorType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000043) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeACCompressorTypeWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("Thermostat ACCompressorType write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatACCompressorType : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACCompressorType()
        : SubscribeAttribute("accompressor-type")
    {
    }

    ~SubscribeAttributeThermostatACCompressorType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000043) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACCompressorTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACCompressorType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACErrorCode
 */
class ReadThermostatACErrorCode : public ReadAttribute {
public:
    ReadThermostatACErrorCode()
        : ReadAttribute("acerror-code")
    {
    }

    ~ReadThermostatACErrorCode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000044) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACErrorCodeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACErrorCode response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACErrorCode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatACErrorCode : public WriteAttribute {
public:
    WriteThermostatACErrorCode()
        : WriteAttribute("acerror-code")
    {
        AddArgument("attr-name", "acerror-code");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatACErrorCode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000044) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeACErrorCodeWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("Thermostat ACErrorCode write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeThermostatACErrorCode : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACErrorCode()
        : SubscribeAttribute("acerror-code")
    {
    }

    ~SubscribeAttributeThermostatACErrorCode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000044) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACErrorCodeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACErrorCode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACLouverPosition
 */
class ReadThermostatACLouverPosition : public ReadAttribute {
public:
    ReadThermostatACLouverPosition()
        : ReadAttribute("aclouver-position")
    {
    }

    ~ReadThermostatACLouverPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000045) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACLouverPositionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACLouverPosition response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACLouverPosition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatACLouverPosition : public WriteAttribute {
public:
    WriteThermostatACLouverPosition()
        : WriteAttribute("aclouver-position")
    {
        AddArgument("attr-name", "aclouver-position");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatACLouverPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000045) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeACLouverPositionWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("Thermostat ACLouverPosition write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatACLouverPosition : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACLouverPosition()
        : SubscribeAttribute("aclouver-position")
    {
    }

    ~SubscribeAttributeThermostatACLouverPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000045) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACLouverPositionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACLouverPosition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACCoilTemperature
 */
class ReadThermostatACCoilTemperature : public ReadAttribute {
public:
    ReadThermostatACCoilTemperature()
        : ReadAttribute("accoil-temperature")
    {
    }

    ~ReadThermostatACCoilTemperature() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000046) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACCoilTemperatureWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACCoilTemperature response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACCoilTemperature read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatACCoilTemperature : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACCoilTemperature()
        : SubscribeAttribute("accoil-temperature")
    {
    }

    ~SubscribeAttributeThermostatACCoilTemperature() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000046) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACCoilTemperatureWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACCoilTemperature response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ACCapacityformat
 */
class ReadThermostatACCapacityformat : public ReadAttribute {
public:
    ReadThermostatACCapacityformat()
        : ReadAttribute("accapacityformat")
    {
    }

    ~ReadThermostatACCapacityformat() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x00000047) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeACCapacityformatWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ACCapacityformat response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ACCapacityformat read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatACCapacityformat : public WriteAttribute {
public:
    WriteThermostatACCapacityformat()
        : WriteAttribute("accapacityformat")
    {
        AddArgument("attr-name", "accapacityformat");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatACCapacityformat() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) WriteAttribute (0x00000047) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeACCapacityformatWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("Thermostat ACCapacityformat write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatACCapacityformat : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatACCapacityformat()
        : SubscribeAttribute("accapacityformat")
    {
    }

    ~SubscribeAttributeThermostatACCapacityformat() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x00000047) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeACCapacityformatWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ACCapacityformat response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadThermostatGeneratedCommandList : public ReadAttribute {
public:
    ReadThermostatGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadThermostatGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeThermostatGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadThermostatAcceptedCommandList : public ReadAttribute {
public:
    ReadThermostatAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadThermostatAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeThermostatAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadThermostatAttributeList : public ReadAttribute {
public:
    ReadThermostatAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadThermostatAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeThermostatAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadThermostatFeatureMap : public ReadAttribute {
public:
    ReadThermostatFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadThermostatFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeThermostatFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadThermostatClusterRevision : public ReadAttribute {
public:
    ReadThermostatClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadThermostatClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeThermostatClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster FanControl                                                  | 0x0202 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * FanMode                                                           | 0x0000 |
| * FanModeSequence                                                   | 0x0001 |
| * PercentSetting                                                    | 0x0002 |
| * PercentCurrent                                                    | 0x0003 |
| * SpeedMax                                                          | 0x0004 |
| * SpeedSetting                                                      | 0x0005 |
| * SpeedCurrent                                                      | 0x0006 |
| * RockSupport                                                       | 0x0007 |
| * RockSetting                                                       | 0x0008 |
| * WindSupport                                                       | 0x0009 |
| * WindSetting                                                       | 0x000A |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute FanMode
 */
class ReadFanControlFanMode : public ReadAttribute {
public:
    ReadFanControlFanMode()
        : ReadAttribute("fan-mode")
    {
    }

    ~ReadFanControlFanMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFanModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.FanMode response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl FanMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteFanControlFanMode : public WriteAttribute {
public:
    WriteFanControlFanMode()
        : WriteAttribute("fan-mode")
    {
        AddArgument("attr-name", "fan-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteFanControlFanMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeFanModeWithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("FanControl FanMode write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeFanControlFanMode : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlFanMode()
        : SubscribeAttribute("fan-mode")
    {
    }

    ~SubscribeAttributeFanControlFanMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFanModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.FanMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FanModeSequence
 */
class ReadFanControlFanModeSequence : public ReadAttribute {
public:
    ReadFanControlFanModeSequence()
        : ReadAttribute("fan-mode-sequence")
    {
    }

    ~ReadFanControlFanModeSequence() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFanModeSequenceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.FanModeSequence response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl FanModeSequence read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteFanControlFanModeSequence : public WriteAttribute {
public:
    WriteFanControlFanModeSequence()
        : WriteAttribute("fan-mode-sequence")
    {
        AddArgument("attr-name", "fan-mode-sequence");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteFanControlFanModeSequence() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) WriteAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeFanModeSequenceWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("FanControl FanModeSequence write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeFanControlFanModeSequence : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlFanModeSequence()
        : SubscribeAttribute("fan-mode-sequence")
    {
    }

    ~SubscribeAttributeFanControlFanModeSequence() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFanModeSequenceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.FanModeSequence response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PercentSetting
 */
class ReadFanControlPercentSetting : public ReadAttribute {
public:
    ReadFanControlPercentSetting()
        : ReadAttribute("percent-setting")
    {
    }

    ~ReadFanControlPercentSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributePercentSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.PercentSetting response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl PercentSetting read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteFanControlPercentSetting : public WriteAttribute {
public:
    WriteFanControlPercentSetting()
        : WriteAttribute("percent-setting")
    {
        AddArgument("attr-name", "percent-setting");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteFanControlPercentSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) WriteAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributePercentSettingWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("FanControl PercentSetting write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeFanControlPercentSetting : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlPercentSetting()
        : SubscribeAttribute("percent-setting")
    {
    }

    ~SubscribeAttributeFanControlPercentSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePercentSettingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.PercentSetting response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PercentCurrent
 */
class ReadFanControlPercentCurrent : public ReadAttribute {
public:
    ReadFanControlPercentCurrent()
        : ReadAttribute("percent-current")
    {
    }

    ~ReadFanControlPercentCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributePercentCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.PercentCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl PercentCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlPercentCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlPercentCurrent()
        : SubscribeAttribute("percent-current")
    {
    }

    ~SubscribeAttributeFanControlPercentCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePercentCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.PercentCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SpeedMax
 */
class ReadFanControlSpeedMax : public ReadAttribute {
public:
    ReadFanControlSpeedMax()
        : ReadAttribute("speed-max")
    {
    }

    ~ReadFanControlSpeedMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSpeedMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.SpeedMax response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl SpeedMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlSpeedMax : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlSpeedMax()
        : SubscribeAttribute("speed-max")
    {
    }

    ~SubscribeAttributeFanControlSpeedMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSpeedMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.SpeedMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SpeedSetting
 */
class ReadFanControlSpeedSetting : public ReadAttribute {
public:
    ReadFanControlSpeedSetting()
        : ReadAttribute("speed-setting")
    {
    }

    ~ReadFanControlSpeedSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSpeedSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.SpeedSetting response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl SpeedSetting read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteFanControlSpeedSetting : public WriteAttribute {
public:
    WriteFanControlSpeedSetting()
        : WriteAttribute("speed-setting")
    {
        AddArgument("attr-name", "speed-setting");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteFanControlSpeedSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) WriteAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeSpeedSettingWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("FanControl SpeedSetting write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeFanControlSpeedSetting : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlSpeedSetting()
        : SubscribeAttribute("speed-setting")
    {
    }

    ~SubscribeAttributeFanControlSpeedSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSpeedSettingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.SpeedSetting response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SpeedCurrent
 */
class ReadFanControlSpeedCurrent : public ReadAttribute {
public:
    ReadFanControlSpeedCurrent()
        : ReadAttribute("speed-current")
    {
    }

    ~ReadFanControlSpeedCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeSpeedCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.SpeedCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl SpeedCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlSpeedCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlSpeedCurrent()
        : SubscribeAttribute("speed-current")
    {
    }

    ~SubscribeAttributeFanControlSpeedCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSpeedCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.SpeedCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RockSupport
 */
class ReadFanControlRockSupport : public ReadAttribute {
public:
    ReadFanControlRockSupport()
        : ReadAttribute("rock-support")
    {
    }

    ~ReadFanControlRockSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeRockSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.RockSupport response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl RockSupport read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlRockSupport : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlRockSupport()
        : SubscribeAttribute("rock-support")
    {
    }

    ~SubscribeAttributeFanControlRockSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRockSupportWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.RockSupport response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RockSetting
 */
class ReadFanControlRockSetting : public ReadAttribute {
public:
    ReadFanControlRockSetting()
        : ReadAttribute("rock-setting")
    {
    }

    ~ReadFanControlRockSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeRockSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.RockSetting response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl RockSetting read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteFanControlRockSetting : public WriteAttribute {
public:
    WriteFanControlRockSetting()
        : WriteAttribute("rock-setting")
    {
        AddArgument("attr-name", "rock-setting");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteFanControlRockSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) WriteAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeRockSettingWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("FanControl RockSetting write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeFanControlRockSetting : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlRockSetting()
        : SubscribeAttribute("rock-setting")
    {
    }

    ~SubscribeAttributeFanControlRockSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRockSettingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.RockSetting response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WindSupport
 */
class ReadFanControlWindSupport : public ReadAttribute {
public:
    ReadFanControlWindSupport()
        : ReadAttribute("wind-support")
    {
    }

    ~ReadFanControlWindSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeWindSupportWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.WindSupport response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl WindSupport read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlWindSupport : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlWindSupport()
        : SubscribeAttribute("wind-support")
    {
    }

    ~SubscribeAttributeFanControlWindSupport() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWindSupportWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.WindSupport response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WindSetting
 */
class ReadFanControlWindSetting : public ReadAttribute {
public:
    ReadFanControlWindSetting()
        : ReadAttribute("wind-setting")
    {
    }

    ~ReadFanControlWindSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeWindSettingWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.WindSetting response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl WindSetting read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteFanControlWindSetting : public WriteAttribute {
public:
    WriteFanControlWindSetting()
        : WriteAttribute("wind-setting")
    {
        AddArgument("attr-name", "wind-setting");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteFanControlWindSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) WriteAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeWindSettingWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("FanControl WindSetting write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeFanControlWindSetting : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlWindSetting()
        : SubscribeAttribute("wind-setting")
    {
    }

    ~SubscribeAttributeFanControlWindSetting() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWindSettingWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.WindSetting response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadFanControlGeneratedCommandList : public ReadAttribute {
public:
    ReadFanControlGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadFanControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeFanControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadFanControlAcceptedCommandList : public ReadAttribute {
public:
    ReadFanControlAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadFanControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeFanControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadFanControlAttributeList : public ReadAttribute {
public:
    ReadFanControlAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadFanControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeFanControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadFanControlFeatureMap : public ReadAttribute {
public:
    ReadFanControlFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadFanControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeFanControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadFanControlClusterRevision : public ReadAttribute {
public:
    ReadFanControlClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadFanControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeFanControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ThermostatUserInterfaceConfiguration                        | 0x0204 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * TemperatureDisplayMode                                            | 0x0000 |
| * KeypadLockout                                                     | 0x0001 |
| * ScheduleProgrammingVisibility                                     | 0x0002 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute TemperatureDisplayMode
 */
class ReadThermostatUserInterfaceConfigurationTemperatureDisplayMode : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationTemperatureDisplayMode()
        : ReadAttribute("temperature-display-mode")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationTemperatureDisplayMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeTemperatureDisplayModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.TemperatureDisplayMode response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration TemperatureDisplayMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatUserInterfaceConfigurationTemperatureDisplayMode : public WriteAttribute {
public:
    WriteThermostatUserInterfaceConfigurationTemperatureDisplayMode()
        : WriteAttribute("temperature-display-mode")
    {
        AddArgument("attr-name", "temperature-display-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatUserInterfaceConfigurationTemperatureDisplayMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeTemperatureDisplayModeWithValue:value
                                                        params:params
                                                    completion:^(NSError * _Nullable error) {
                                                        if (error != nil) {
                                                            LogNSError("ThermostatUserInterfaceConfiguration "
                                                                       "TemperatureDisplayMode write Error",
                                                                error);
                                                        }
                                                        SetCommandExitStatus(error);
                                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatUserInterfaceConfigurationTemperatureDisplayMode : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationTemperatureDisplayMode()
        : SubscribeAttribute("temperature-display-mode")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationTemperatureDisplayMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTemperatureDisplayModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.TemperatureDisplayMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute KeypadLockout
 */
class ReadThermostatUserInterfaceConfigurationKeypadLockout : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationKeypadLockout()
        : ReadAttribute("keypad-lockout")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationKeypadLockout() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeKeypadLockoutWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.KeypadLockout response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration KeypadLockout read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatUserInterfaceConfigurationKeypadLockout : public WriteAttribute {
public:
    WriteThermostatUserInterfaceConfigurationKeypadLockout()
        : WriteAttribute("keypad-lockout")
    {
        AddArgument("attr-name", "keypad-lockout");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatUserInterfaceConfigurationKeypadLockout() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) WriteAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster
            writeAttributeKeypadLockoutWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("ThermostatUserInterfaceConfiguration KeypadLockout write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatUserInterfaceConfigurationKeypadLockout : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationKeypadLockout()
        : SubscribeAttribute("keypad-lockout")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationKeypadLockout() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeKeypadLockoutWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.KeypadLockout response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ScheduleProgrammingVisibility
 */
class ReadThermostatUserInterfaceConfigurationScheduleProgrammingVisibility : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationScheduleProgrammingVisibility()
        : ReadAttribute("schedule-programming-visibility")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationScheduleProgrammingVisibility() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeScheduleProgrammingVisibilityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.ScheduleProgrammingVisibility response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration ScheduleProgrammingVisibility read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteThermostatUserInterfaceConfigurationScheduleProgrammingVisibility : public WriteAttribute {
public:
    WriteThermostatUserInterfaceConfigurationScheduleProgrammingVisibility()
        : WriteAttribute("schedule-programming-visibility")
    {
        AddArgument("attr-name", "schedule-programming-visibility");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteThermostatUserInterfaceConfigurationScheduleProgrammingVisibility() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) WriteAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeScheduleProgrammingVisibilityWithValue:value
                                                               params:params
                                                           completion:^(NSError * _Nullable error) {
                                                               if (error != nil) {
                                                                   LogNSError("ThermostatUserInterfaceConfiguration "
                                                                              "ScheduleProgrammingVisibility write Error",
                                                                       error);
                                                               }
                                                               SetCommandExitStatus(error);
                                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeThermostatUserInterfaceConfigurationScheduleProgrammingVisibility : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationScheduleProgrammingVisibility()
        : SubscribeAttribute("schedule-programming-visibility")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationScheduleProgrammingVisibility() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeScheduleProgrammingVisibilityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.ScheduleProgrammingVisibility response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadThermostatUserInterfaceConfigurationGeneratedCommandList : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUserInterfaceConfigurationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadThermostatUserInterfaceConfigurationAcceptedCommandList : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUserInterfaceConfigurationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadThermostatUserInterfaceConfigurationAttributeList : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUserInterfaceConfigurationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadThermostatUserInterfaceConfigurationFeatureMap : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUserInterfaceConfigurationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadThermostatUserInterfaceConfigurationClusterRevision : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUserInterfaceConfigurationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device
                                                                                                endpointID:@(endpointId)
                                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ColorControl                                                | 0x0300 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * MoveToHue                                                         |   0x00 |
| * MoveHue                                                           |   0x01 |
| * StepHue                                                           |   0x02 |
| * MoveToSaturation                                                  |   0x03 |
| * MoveSaturation                                                    |   0x04 |
| * StepSaturation                                                    |   0x05 |
| * MoveToHueAndSaturation                                            |   0x06 |
| * MoveToColor                                                       |   0x07 |
| * MoveColor                                                         |   0x08 |
| * StepColor                                                         |   0x09 |
| * MoveToColorTemperature                                            |   0x0A |
| * EnhancedMoveToHue                                                 |   0x40 |
| * EnhancedMoveHue                                                   |   0x41 |
| * EnhancedStepHue                                                   |   0x42 |
| * EnhancedMoveToHueAndSaturation                                    |   0x43 |
| * ColorLoopSet                                                      |   0x44 |
| * StopMoveStep                                                      |   0x47 |
| * MoveColorTemperature                                              |   0x4B |
| * StepColorTemperature                                              |   0x4C |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * CurrentHue                                                        | 0x0000 |
| * CurrentSaturation                                                 | 0x0001 |
| * RemainingTime                                                     | 0x0002 |
| * CurrentX                                                          | 0x0003 |
| * CurrentY                                                          | 0x0004 |
| * DriftCompensation                                                 | 0x0005 |
| * CompensationText                                                  | 0x0006 |
| * ColorTemperatureMireds                                            | 0x0007 |
| * ColorMode                                                         | 0x0008 |
| * Options                                                           | 0x000F |
| * NumberOfPrimaries                                                 | 0x0010 |
| * Primary1X                                                         | 0x0011 |
| * Primary1Y                                                         | 0x0012 |
| * Primary1Intensity                                                 | 0x0013 |
| * Primary2X                                                         | 0x0015 |
| * Primary2Y                                                         | 0x0016 |
| * Primary2Intensity                                                 | 0x0017 |
| * Primary3X                                                         | 0x0019 |
| * Primary3Y                                                         | 0x001A |
| * Primary3Intensity                                                 | 0x001B |
| * Primary4X                                                         | 0x0020 |
| * Primary4Y                                                         | 0x0021 |
| * Primary4Intensity                                                 | 0x0022 |
| * Primary5X                                                         | 0x0024 |
| * Primary5Y                                                         | 0x0025 |
| * Primary5Intensity                                                 | 0x0026 |
| * Primary6X                                                         | 0x0028 |
| * Primary6Y                                                         | 0x0029 |
| * Primary6Intensity                                                 | 0x002A |
| * WhitePointX                                                       | 0x0030 |
| * WhitePointY                                                       | 0x0031 |
| * ColorPointRX                                                      | 0x0032 |
| * ColorPointRY                                                      | 0x0033 |
| * ColorPointRIntensity                                              | 0x0034 |
| * ColorPointGX                                                      | 0x0036 |
| * ColorPointGY                                                      | 0x0037 |
| * ColorPointGIntensity                                              | 0x0038 |
| * ColorPointBX                                                      | 0x003A |
| * ColorPointBY                                                      | 0x003B |
| * ColorPointBIntensity                                              | 0x003C |
| * EnhancedCurrentHue                                                | 0x4000 |
| * EnhancedColorMode                                                 | 0x4001 |
| * ColorLoopActive                                                   | 0x4002 |
| * ColorLoopDirection                                                | 0x4003 |
| * ColorLoopTime                                                     | 0x4004 |
| * ColorLoopStartEnhancedHue                                         | 0x4005 |
| * ColorLoopStoredEnhancedHue                                        | 0x4006 |
| * ColorCapabilities                                                 | 0x400A |
| * ColorTempPhysicalMinMireds                                        | 0x400B |
| * ColorTempPhysicalMaxMireds                                        | 0x400C |
| * CoupleColorTempToLevelMinMireds                                   | 0x400D |
| * StartUpColorTemperatureMireds                                     | 0x4010 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command MoveToHue
 */
class ColorControlMoveToHue : public ClusterCommand {
public:
    ColorControlMoveToHue()
        : ClusterCommand("move-to-hue")
    {
        AddArgument("Hue", 0, UINT8_MAX, &mRequest.hue);
        AddArgument("Direction", 0, UINT8_MAX, &mRequest.direction);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveToHueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.hue = [NSNumber numberWithUnsignedChar:mRequest.hue];
        params.direction = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.direction)];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToHueWithParams:params
                              completion:^(NSError * _Nullable error) {
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveToHue::Type mRequest;
};

/*
 * Command MoveHue
 */
class ColorControlMoveHue : public ClusterCommand {
public:
    ColorControlMoveHue()
        : ClusterCommand("move-hue")
    {
        AddArgument("MoveMode", 0, UINT8_MAX, &mRequest.moveMode);
        AddArgument("Rate", 0, UINT8_MAX, &mRequest.rate);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveHueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.moveMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.moveMode)];
        params.rate = [NSNumber numberWithUnsignedChar:mRequest.rate];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveHueWithParams:params
                            completion:^(NSError * _Nullable error) {
                                responsesNeeded--;
                                if (error != nil) {
                                    mError = error;
                                    LogNSError("Error", error);
                                }
                                if (responsesNeeded == 0) {
                                    SetCommandExitStatus(mError);
                                }
                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveHue::Type mRequest;
};

/*
 * Command StepHue
 */
class ColorControlStepHue : public ClusterCommand {
public:
    ColorControlStepHue()
        : ClusterCommand("step-hue")
    {
        AddArgument("StepMode", 0, UINT8_MAX, &mRequest.stepMode);
        AddArgument("StepSize", 0, UINT8_MAX, &mRequest.stepSize);
        AddArgument("TransitionTime", 0, UINT8_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterStepHueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.stepMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.stepMode)];
        params.stepSize = [NSNumber numberWithUnsignedChar:mRequest.stepSize];
        params.transitionTime = [NSNumber numberWithUnsignedChar:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stepHueWithParams:params
                            completion:^(NSError * _Nullable error) {
                                responsesNeeded--;
                                if (error != nil) {
                                    mError = error;
                                    LogNSError("Error", error);
                                }
                                if (responsesNeeded == 0) {
                                    SetCommandExitStatus(mError);
                                }
                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::StepHue::Type mRequest;
};

/*
 * Command MoveToSaturation
 */
class ColorControlMoveToSaturation : public ClusterCommand {
public:
    ColorControlMoveToSaturation()
        : ClusterCommand("move-to-saturation")
    {
        AddArgument("Saturation", 0, UINT8_MAX, &mRequest.saturation);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveToSaturationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.saturation = [NSNumber numberWithUnsignedChar:mRequest.saturation];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToSaturationWithParams:params
                                     completion:^(NSError * _Nullable error) {
                                         responsesNeeded--;
                                         if (error != nil) {
                                             mError = error;
                                             LogNSError("Error", error);
                                         }
                                         if (responsesNeeded == 0) {
                                             SetCommandExitStatus(mError);
                                         }
                                     }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveToSaturation::Type mRequest;
};

/*
 * Command MoveSaturation
 */
class ColorControlMoveSaturation : public ClusterCommand {
public:
    ColorControlMoveSaturation()
        : ClusterCommand("move-saturation")
    {
        AddArgument("MoveMode", 0, UINT8_MAX, &mRequest.moveMode);
        AddArgument("Rate", 0, UINT8_MAX, &mRequest.rate);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveSaturationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.moveMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.moveMode)];
        params.rate = [NSNumber numberWithUnsignedChar:mRequest.rate];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveSaturationWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveSaturation::Type mRequest;
};

/*
 * Command StepSaturation
 */
class ColorControlStepSaturation : public ClusterCommand {
public:
    ColorControlStepSaturation()
        : ClusterCommand("step-saturation")
    {
        AddArgument("StepMode", 0, UINT8_MAX, &mRequest.stepMode);
        AddArgument("StepSize", 0, UINT8_MAX, &mRequest.stepSize);
        AddArgument("TransitionTime", 0, UINT8_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterStepSaturationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.stepMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.stepMode)];
        params.stepSize = [NSNumber numberWithUnsignedChar:mRequest.stepSize];
        params.transitionTime = [NSNumber numberWithUnsignedChar:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stepSaturationWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::StepSaturation::Type mRequest;
};

/*
 * Command MoveToHueAndSaturation
 */
class ColorControlMoveToHueAndSaturation : public ClusterCommand {
public:
    ColorControlMoveToHueAndSaturation()
        : ClusterCommand("move-to-hue-and-saturation")
    {
        AddArgument("Hue", 0, UINT8_MAX, &mRequest.hue);
        AddArgument("Saturation", 0, UINT8_MAX, &mRequest.saturation);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveToHueAndSaturationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.hue = [NSNumber numberWithUnsignedChar:mRequest.hue];
        params.saturation = [NSNumber numberWithUnsignedChar:mRequest.saturation];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToHueAndSaturationWithParams:params
                                           completion:^(NSError * _Nullable error) {
                                               responsesNeeded--;
                                               if (error != nil) {
                                                   mError = error;
                                                   LogNSError("Error", error);
                                               }
                                               if (responsesNeeded == 0) {
                                                   SetCommandExitStatus(mError);
                                               }
                                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveToHueAndSaturation::Type mRequest;
};

/*
 * Command MoveToColor
 */
class ColorControlMoveToColor : public ClusterCommand {
public:
    ColorControlMoveToColor()
        : ClusterCommand("move-to-color")
    {
        AddArgument("ColorX", 0, UINT16_MAX, &mRequest.colorX);
        AddArgument("ColorY", 0, UINT16_MAX, &mRequest.colorY);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveToColorParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.colorX = [NSNumber numberWithUnsignedShort:mRequest.colorX];
        params.colorY = [NSNumber numberWithUnsignedShort:mRequest.colorY];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToColorWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveToColor::Type mRequest;
};

/*
 * Command MoveColor
 */
class ColorControlMoveColor : public ClusterCommand {
public:
    ColorControlMoveColor()
        : ClusterCommand("move-color")
    {
        AddArgument("RateX", INT16_MIN, INT16_MAX, &mRequest.rateX);
        AddArgument("RateY", INT16_MIN, INT16_MAX, &mRequest.rateY);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveColorParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.rateX = [NSNumber numberWithShort:mRequest.rateX];
        params.rateY = [NSNumber numberWithShort:mRequest.rateY];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveColorWithParams:params
                              completion:^(NSError * _Nullable error) {
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveColor::Type mRequest;
};

/*
 * Command StepColor
 */
class ColorControlStepColor : public ClusterCommand {
public:
    ColorControlStepColor()
        : ClusterCommand("step-color")
    {
        AddArgument("StepX", INT16_MIN, INT16_MAX, &mRequest.stepX);
        AddArgument("StepY", INT16_MIN, INT16_MAX, &mRequest.stepY);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterStepColorParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.stepX = [NSNumber numberWithShort:mRequest.stepX];
        params.stepY = [NSNumber numberWithShort:mRequest.stepY];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stepColorWithParams:params
                              completion:^(NSError * _Nullable error) {
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::StepColor::Type mRequest;
};

/*
 * Command MoveToColorTemperature
 */
class ColorControlMoveToColorTemperature : public ClusterCommand {
public:
    ColorControlMoveToColorTemperature()
        : ClusterCommand("move-to-color-temperature")
    {
        AddArgument("ColorTemperatureMireds", 0, UINT16_MAX, &mRequest.colorTemperatureMireds);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveToColorTemperatureParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.colorTemperatureMireds = [NSNumber numberWithUnsignedShort:mRequest.colorTemperatureMireds];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveToColorTemperatureWithParams:params
                                           completion:^(NSError * _Nullable error) {
                                               responsesNeeded--;
                                               if (error != nil) {
                                                   mError = error;
                                                   LogNSError("Error", error);
                                               }
                                               if (responsesNeeded == 0) {
                                                   SetCommandExitStatus(mError);
                                               }
                                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveToColorTemperature::Type mRequest;
};

/*
 * Command EnhancedMoveToHue
 */
class ColorControlEnhancedMoveToHue : public ClusterCommand {
public:
    ColorControlEnhancedMoveToHue()
        : ClusterCommand("enhanced-move-to-hue")
    {
        AddArgument("EnhancedHue", 0, UINT16_MAX, &mRequest.enhancedHue);
        AddArgument("Direction", 0, UINT8_MAX, &mRequest.direction);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000040) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterEnhancedMoveToHueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.enhancedHue = [NSNumber numberWithUnsignedShort:mRequest.enhancedHue];
        params.direction = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.direction)];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enhancedMoveToHueWithParams:params
                                      completion:^(NSError * _Nullable error) {
                                          responsesNeeded--;
                                          if (error != nil) {
                                              mError = error;
                                              LogNSError("Error", error);
                                          }
                                          if (responsesNeeded == 0) {
                                              SetCommandExitStatus(mError);
                                          }
                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::EnhancedMoveToHue::Type mRequest;
};

/*
 * Command EnhancedMoveHue
 */
class ColorControlEnhancedMoveHue : public ClusterCommand {
public:
    ColorControlEnhancedMoveHue()
        : ClusterCommand("enhanced-move-hue")
    {
        AddArgument("MoveMode", 0, UINT8_MAX, &mRequest.moveMode);
        AddArgument("Rate", 0, UINT16_MAX, &mRequest.rate);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000041) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterEnhancedMoveHueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.moveMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.moveMode)];
        params.rate = [NSNumber numberWithUnsignedShort:mRequest.rate];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enhancedMoveHueWithParams:params
                                    completion:^(NSError * _Nullable error) {
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::EnhancedMoveHue::Type mRequest;
};

/*
 * Command EnhancedStepHue
 */
class ColorControlEnhancedStepHue : public ClusterCommand {
public:
    ColorControlEnhancedStepHue()
        : ClusterCommand("enhanced-step-hue")
    {
        AddArgument("StepMode", 0, UINT8_MAX, &mRequest.stepMode);
        AddArgument("StepSize", 0, UINT16_MAX, &mRequest.stepSize);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000042) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterEnhancedStepHueParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.stepMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.stepMode)];
        params.stepSize = [NSNumber numberWithUnsignedShort:mRequest.stepSize];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enhancedStepHueWithParams:params
                                    completion:^(NSError * _Nullable error) {
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::EnhancedStepHue::Type mRequest;
};

/*
 * Command EnhancedMoveToHueAndSaturation
 */
class ColorControlEnhancedMoveToHueAndSaturation : public ClusterCommand {
public:
    ColorControlEnhancedMoveToHueAndSaturation()
        : ClusterCommand("enhanced-move-to-hue-and-saturation")
    {
        AddArgument("EnhancedHue", 0, UINT16_MAX, &mRequest.enhancedHue);
        AddArgument("Saturation", 0, UINT8_MAX, &mRequest.saturation);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000043) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterEnhancedMoveToHueAndSaturationParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.enhancedHue = [NSNumber numberWithUnsignedShort:mRequest.enhancedHue];
        params.saturation = [NSNumber numberWithUnsignedChar:mRequest.saturation];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster enhancedMoveToHueAndSaturationWithParams:params
                                                   completion:^(NSError * _Nullable error) {
                                                       responsesNeeded--;
                                                       if (error != nil) {
                                                           mError = error;
                                                           LogNSError("Error", error);
                                                       }
                                                       if (responsesNeeded == 0) {
                                                           SetCommandExitStatus(mError);
                                                       }
                                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::EnhancedMoveToHueAndSaturation::Type mRequest;
};

/*
 * Command ColorLoopSet
 */
class ColorControlColorLoopSet : public ClusterCommand {
public:
    ColorControlColorLoopSet()
        : ClusterCommand("color-loop-set")
    {
        AddArgument("UpdateFlags", 0, UINT8_MAX, &mRequest.updateFlags);
        AddArgument("Action", 0, UINT8_MAX, &mRequest.action);
        AddArgument("Direction", 0, UINT8_MAX, &mRequest.direction);
        AddArgument("Time", 0, UINT16_MAX, &mRequest.time);
        AddArgument("StartHue", 0, UINT16_MAX, &mRequest.startHue);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000044) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterColorLoopSetParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.updateFlags = [NSNumber numberWithUnsignedChar:mRequest.updateFlags.Raw()];
        params.action = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.action)];
        params.direction = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.direction)];
        params.time = [NSNumber numberWithUnsignedShort:mRequest.time];
        params.startHue = [NSNumber numberWithUnsignedShort:mRequest.startHue];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster colorLoopSetWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::ColorLoopSet::Type mRequest;
};

/*
 * Command StopMoveStep
 */
class ColorControlStopMoveStep : public ClusterCommand {
public:
    ColorControlStopMoveStep()
        : ClusterCommand("stop-move-step")
    {
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x00000047) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterStopMoveStepParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stopMoveStepWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::StopMoveStep::Type mRequest;
};

/*
 * Command MoveColorTemperature
 */
class ColorControlMoveColorTemperature : public ClusterCommand {
public:
    ColorControlMoveColorTemperature()
        : ClusterCommand("move-color-temperature")
    {
        AddArgument("MoveMode", 0, UINT8_MAX, &mRequest.moveMode);
        AddArgument("Rate", 0, UINT16_MAX, &mRequest.rate);
        AddArgument("ColorTemperatureMinimumMireds", 0, UINT16_MAX, &mRequest.colorTemperatureMinimumMireds);
        AddArgument("ColorTemperatureMaximumMireds", 0, UINT16_MAX, &mRequest.colorTemperatureMaximumMireds);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x0000004B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterMoveColorTemperatureParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.moveMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.moveMode)];
        params.rate = [NSNumber numberWithUnsignedShort:mRequest.rate];
        params.colorTemperatureMinimumMireds = [NSNumber numberWithUnsignedShort:mRequest.colorTemperatureMinimumMireds];
        params.colorTemperatureMaximumMireds = [NSNumber numberWithUnsignedShort:mRequest.colorTemperatureMaximumMireds];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster moveColorTemperatureWithParams:params
                                         completion:^(NSError * _Nullable error) {
                                             responsesNeeded--;
                                             if (error != nil) {
                                                 mError = error;
                                                 LogNSError("Error", error);
                                             }
                                             if (responsesNeeded == 0) {
                                                 SetCommandExitStatus(mError);
                                             }
                                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::MoveColorTemperature::Type mRequest;
};

/*
 * Command StepColorTemperature
 */
class ColorControlStepColorTemperature : public ClusterCommand {
public:
    ColorControlStepColorTemperature()
        : ClusterCommand("step-color-temperature")
    {
        AddArgument("StepMode", 0, UINT8_MAX, &mRequest.stepMode);
        AddArgument("StepSize", 0, UINT16_MAX, &mRequest.stepSize);
        AddArgument("TransitionTime", 0, UINT16_MAX, &mRequest.transitionTime);
        AddArgument("ColorTemperatureMinimumMireds", 0, UINT16_MAX, &mRequest.colorTemperatureMinimumMireds);
        AddArgument("ColorTemperatureMaximumMireds", 0, UINT16_MAX, &mRequest.colorTemperatureMaximumMireds);
        AddArgument("OptionsMask", 0, UINT8_MAX, &mRequest.optionsMask);
        AddArgument("OptionsOverride", 0, UINT8_MAX, &mRequest.optionsOverride);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) command (0x0000004C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRColorControlClusterStepColorTemperatureParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.stepMode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.stepMode)];
        params.stepSize = [NSNumber numberWithUnsignedShort:mRequest.stepSize];
        params.transitionTime = [NSNumber numberWithUnsignedShort:mRequest.transitionTime];
        params.colorTemperatureMinimumMireds = [NSNumber numberWithUnsignedShort:mRequest.colorTemperatureMinimumMireds];
        params.colorTemperatureMaximumMireds = [NSNumber numberWithUnsignedShort:mRequest.colorTemperatureMaximumMireds];
        params.optionsMask = [NSNumber numberWithUnsignedChar:mRequest.optionsMask];
        params.optionsOverride = [NSNumber numberWithUnsignedChar:mRequest.optionsOverride];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stepColorTemperatureWithParams:params
                                         completion:^(NSError * _Nullable error) {
                                             responsesNeeded--;
                                             if (error != nil) {
                                                 mError = error;
                                                 LogNSError("Error", error);
                                             }
                                             if (responsesNeeded == 0) {
                                                 SetCommandExitStatus(mError);
                                             }
                                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ColorControl::Commands::StepColorTemperature::Type mRequest;
};

/*
 * Attribute CurrentHue
 */
class ReadColorControlCurrentHue : public ReadAttribute {
public:
    ReadColorControlCurrentHue()
        : ReadAttribute("current-hue")
    {
    }

    ~ReadColorControlCurrentHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeCurrentHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.CurrentHue response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl CurrentHue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlCurrentHue : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlCurrentHue()
        : SubscribeAttribute("current-hue")
    {
    }

    ~SubscribeAttributeColorControlCurrentHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentHueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.CurrentHue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentSaturation
 */
class ReadColorControlCurrentSaturation : public ReadAttribute {
public:
    ReadColorControlCurrentSaturation()
        : ReadAttribute("current-saturation")
    {
    }

    ~ReadColorControlCurrentSaturation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeCurrentSaturationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.CurrentSaturation response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl CurrentSaturation read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlCurrentSaturation : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlCurrentSaturation()
        : SubscribeAttribute("current-saturation")
    {
    }

    ~SubscribeAttributeColorControlCurrentSaturation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentSaturationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.CurrentSaturation response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RemainingTime
 */
class ReadColorControlRemainingTime : public ReadAttribute {
public:
    ReadColorControlRemainingTime()
        : ReadAttribute("remaining-time")
    {
    }

    ~ReadColorControlRemainingTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeRemainingTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.RemainingTime response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl RemainingTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlRemainingTime : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlRemainingTime()
        : SubscribeAttribute("remaining-time")
    {
    }

    ~SubscribeAttributeColorControlRemainingTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRemainingTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.RemainingTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentX
 */
class ReadColorControlCurrentX : public ReadAttribute {
public:
    ReadColorControlCurrentX()
        : ReadAttribute("current-x")
    {
    }

    ~ReadColorControlCurrentX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeCurrentXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.CurrentX response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl CurrentX read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlCurrentX : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlCurrentX()
        : SubscribeAttribute("current-x")
    {
    }

    ~SubscribeAttributeColorControlCurrentX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentXWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.CurrentX response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentY
 */
class ReadColorControlCurrentY : public ReadAttribute {
public:
    ReadColorControlCurrentY()
        : ReadAttribute("current-y")
    {
    }

    ~ReadColorControlCurrentY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeCurrentYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.CurrentY response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl CurrentY read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlCurrentY : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlCurrentY()
        : SubscribeAttribute("current-y")
    {
    }

    ~SubscribeAttributeColorControlCurrentY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentYWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.CurrentY response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DriftCompensation
 */
class ReadColorControlDriftCompensation : public ReadAttribute {
public:
    ReadColorControlDriftCompensation()
        : ReadAttribute("drift-compensation")
    {
    }

    ~ReadColorControlDriftCompensation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeDriftCompensationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.DriftCompensation response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl DriftCompensation read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlDriftCompensation : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlDriftCompensation()
        : SubscribeAttribute("drift-compensation")
    {
    }

    ~SubscribeAttributeColorControlDriftCompensation() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDriftCompensationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.DriftCompensation response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CompensationText
 */
class ReadColorControlCompensationText : public ReadAttribute {
public:
    ReadColorControlCompensationText()
        : ReadAttribute("compensation-text")
    {
    }

    ~ReadColorControlCompensationText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeCompensationTextWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.CompensationText response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl CompensationText read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlCompensationText : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlCompensationText()
        : SubscribeAttribute("compensation-text")
    {
    }

    ~SubscribeAttributeColorControlCompensationText() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCompensationTextWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.CompensationText response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorTemperatureMireds
 */
class ReadColorControlColorTemperatureMireds : public ReadAttribute {
public:
    ReadColorControlColorTemperatureMireds()
        : ReadAttribute("color-temperature-mireds")
    {
    }

    ~ReadColorControlColorTemperatureMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorTemperatureMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorTemperatureMireds response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorTemperatureMireds read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorTemperatureMireds : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorTemperatureMireds()
        : SubscribeAttribute("color-temperature-mireds")
    {
    }

    ~SubscribeAttributeColorControlColorTemperatureMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorTemperatureMiredsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorTemperatureMireds response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorMode
 */
class ReadColorControlColorMode : public ReadAttribute {
public:
    ReadColorControlColorMode()
        : ReadAttribute("color-mode")
    {
    }

    ~ReadColorControlColorMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorMode response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorMode : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorMode()
        : SubscribeAttribute("color-mode")
    {
    }

    ~SubscribeAttributeColorControlColorMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Options
 */
class ReadColorControlOptions : public ReadAttribute {
public:
    ReadColorControlOptions()
        : ReadAttribute("options")
    {
    }

    ~ReadColorControlOptions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeOptionsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Options response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Options read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlOptions : public WriteAttribute {
public:
    WriteColorControlOptions()
        : WriteAttribute("options")
    {
        AddArgument("attr-name", "options");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlOptions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOptionsWithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("ColorControl Options write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeColorControlOptions : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlOptions()
        : SubscribeAttribute("options")
    {
    }

    ~SubscribeAttributeColorControlOptions() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOptionsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Options response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NumberOfPrimaries
 */
class ReadColorControlNumberOfPrimaries : public ReadAttribute {
public:
    ReadColorControlNumberOfPrimaries()
        : ReadAttribute("number-of-primaries")
    {
    }

    ~ReadColorControlNumberOfPrimaries() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeNumberOfPrimariesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.NumberOfPrimaries response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl NumberOfPrimaries read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlNumberOfPrimaries : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlNumberOfPrimaries()
        : SubscribeAttribute("number-of-primaries")
    {
    }

    ~SubscribeAttributeColorControlNumberOfPrimaries() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNumberOfPrimariesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.NumberOfPrimaries response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary1X
 */
class ReadColorControlPrimary1X : public ReadAttribute {
public:
    ReadColorControlPrimary1X()
        : ReadAttribute("primary1x")
    {
    }

    ~ReadColorControlPrimary1X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary1XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary1X response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary1X read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary1X : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary1X()
        : SubscribeAttribute("primary1x")
    {
    }

    ~SubscribeAttributeColorControlPrimary1X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary1XWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary1X response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary1Y
 */
class ReadColorControlPrimary1Y : public ReadAttribute {
public:
    ReadColorControlPrimary1Y()
        : ReadAttribute("primary1y")
    {
    }

    ~ReadColorControlPrimary1Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary1YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary1Y response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary1Y read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary1Y : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary1Y()
        : SubscribeAttribute("primary1y")
    {
    }

    ~SubscribeAttributeColorControlPrimary1Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary1YWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary1Y response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary1Intensity
 */
class ReadColorControlPrimary1Intensity : public ReadAttribute {
public:
    ReadColorControlPrimary1Intensity()
        : ReadAttribute("primary1intensity")
    {
    }

    ~ReadColorControlPrimary1Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary1IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary1Intensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary1Intensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary1Intensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary1Intensity()
        : SubscribeAttribute("primary1intensity")
    {
    }

    ~SubscribeAttributeColorControlPrimary1Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary1IntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary1Intensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary2X
 */
class ReadColorControlPrimary2X : public ReadAttribute {
public:
    ReadColorControlPrimary2X()
        : ReadAttribute("primary2x")
    {
    }

    ~ReadColorControlPrimary2X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary2XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary2X response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary2X read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary2X : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary2X()
        : SubscribeAttribute("primary2x")
    {
    }

    ~SubscribeAttributeColorControlPrimary2X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary2XWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary2X response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary2Y
 */
class ReadColorControlPrimary2Y : public ReadAttribute {
public:
    ReadColorControlPrimary2Y()
        : ReadAttribute("primary2y")
    {
    }

    ~ReadColorControlPrimary2Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary2YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary2Y response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary2Y read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary2Y : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary2Y()
        : SubscribeAttribute("primary2y")
    {
    }

    ~SubscribeAttributeColorControlPrimary2Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary2YWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary2Y response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary2Intensity
 */
class ReadColorControlPrimary2Intensity : public ReadAttribute {
public:
    ReadColorControlPrimary2Intensity()
        : ReadAttribute("primary2intensity")
    {
    }

    ~ReadColorControlPrimary2Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary2IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary2Intensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary2Intensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary2Intensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary2Intensity()
        : SubscribeAttribute("primary2intensity")
    {
    }

    ~SubscribeAttributeColorControlPrimary2Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary2IntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary2Intensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary3X
 */
class ReadColorControlPrimary3X : public ReadAttribute {
public:
    ReadColorControlPrimary3X()
        : ReadAttribute("primary3x")
    {
    }

    ~ReadColorControlPrimary3X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000019) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary3XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary3X response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary3X read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary3X : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary3X()
        : SubscribeAttribute("primary3x")
    {
    }

    ~SubscribeAttributeColorControlPrimary3X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary3XWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary3X response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary3Y
 */
class ReadColorControlPrimary3Y : public ReadAttribute {
public:
    ReadColorControlPrimary3Y()
        : ReadAttribute("primary3y")
    {
    }

    ~ReadColorControlPrimary3Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary3YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary3Y response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary3Y read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary3Y : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary3Y()
        : SubscribeAttribute("primary3y")
    {
    }

    ~SubscribeAttributeColorControlPrimary3Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary3YWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary3Y response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary3Intensity
 */
class ReadColorControlPrimary3Intensity : public ReadAttribute {
public:
    ReadColorControlPrimary3Intensity()
        : ReadAttribute("primary3intensity")
    {
    }

    ~ReadColorControlPrimary3Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000001B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary3IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary3Intensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary3Intensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary3Intensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary3Intensity()
        : SubscribeAttribute("primary3intensity")
    {
    }

    ~SubscribeAttributeColorControlPrimary3Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary3IntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary3Intensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary4X
 */
class ReadColorControlPrimary4X : public ReadAttribute {
public:
    ReadColorControlPrimary4X()
        : ReadAttribute("primary4x")
    {
    }

    ~ReadColorControlPrimary4X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000020) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary4XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary4X response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary4X read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary4X : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary4X()
        : SubscribeAttribute("primary4x")
    {
    }

    ~SubscribeAttributeColorControlPrimary4X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary4XWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary4X response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary4Y
 */
class ReadColorControlPrimary4Y : public ReadAttribute {
public:
    ReadColorControlPrimary4Y()
        : ReadAttribute("primary4y")
    {
    }

    ~ReadColorControlPrimary4Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000021) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary4YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary4Y response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary4Y read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary4Y : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary4Y()
        : SubscribeAttribute("primary4y")
    {
    }

    ~SubscribeAttributeColorControlPrimary4Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary4YWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary4Y response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary4Intensity
 */
class ReadColorControlPrimary4Intensity : public ReadAttribute {
public:
    ReadColorControlPrimary4Intensity()
        : ReadAttribute("primary4intensity")
    {
    }

    ~ReadColorControlPrimary4Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000022) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary4IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary4Intensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary4Intensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary4Intensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary4Intensity()
        : SubscribeAttribute("primary4intensity")
    {
    }

    ~SubscribeAttributeColorControlPrimary4Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary4IntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary4Intensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary5X
 */
class ReadColorControlPrimary5X : public ReadAttribute {
public:
    ReadColorControlPrimary5X()
        : ReadAttribute("primary5x")
    {
    }

    ~ReadColorControlPrimary5X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000024) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary5XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary5X response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary5X read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary5X : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary5X()
        : SubscribeAttribute("primary5x")
    {
    }

    ~SubscribeAttributeColorControlPrimary5X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary5XWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary5X response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary5Y
 */
class ReadColorControlPrimary5Y : public ReadAttribute {
public:
    ReadColorControlPrimary5Y()
        : ReadAttribute("primary5y")
    {
    }

    ~ReadColorControlPrimary5Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000025) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary5YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary5Y response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary5Y read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary5Y : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary5Y()
        : SubscribeAttribute("primary5y")
    {
    }

    ~SubscribeAttributeColorControlPrimary5Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary5YWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary5Y response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary5Intensity
 */
class ReadColorControlPrimary5Intensity : public ReadAttribute {
public:
    ReadColorControlPrimary5Intensity()
        : ReadAttribute("primary5intensity")
    {
    }

    ~ReadColorControlPrimary5Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000026) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary5IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary5Intensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary5Intensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary5Intensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary5Intensity()
        : SubscribeAttribute("primary5intensity")
    {
    }

    ~SubscribeAttributeColorControlPrimary5Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000026) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary5IntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary5Intensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary6X
 */
class ReadColorControlPrimary6X : public ReadAttribute {
public:
    ReadColorControlPrimary6X()
        : ReadAttribute("primary6x")
    {
    }

    ~ReadColorControlPrimary6X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000028) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary6XWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary6X response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary6X read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary6X : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary6X()
        : SubscribeAttribute("primary6x")
    {
    }

    ~SubscribeAttributeColorControlPrimary6X() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary6XWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary6X response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary6Y
 */
class ReadColorControlPrimary6Y : public ReadAttribute {
public:
    ReadColorControlPrimary6Y()
        : ReadAttribute("primary6y")
    {
    }

    ~ReadColorControlPrimary6Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000029) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary6YWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary6Y response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary6Y read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary6Y : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary6Y()
        : SubscribeAttribute("primary6y")
    {
    }

    ~SubscribeAttributeColorControlPrimary6Y() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary6YWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary6Y response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Primary6Intensity
 */
class ReadColorControlPrimary6Intensity : public ReadAttribute {
public:
    ReadColorControlPrimary6Intensity()
        : ReadAttribute("primary6intensity")
    {
    }

    ~ReadColorControlPrimary6Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000002A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributePrimary6IntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.Primary6Intensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl Primary6Intensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlPrimary6Intensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlPrimary6Intensity()
        : SubscribeAttribute("primary6intensity")
    {
    }

    ~SubscribeAttributeColorControlPrimary6Intensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000002A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePrimary6IntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.Primary6Intensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WhitePointX
 */
class ReadColorControlWhitePointX : public ReadAttribute {
public:
    ReadColorControlWhitePointX()
        : ReadAttribute("white-point-x")
    {
    }

    ~ReadColorControlWhitePointX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000030) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeWhitePointXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.WhitePointX response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl WhitePointX read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlWhitePointX : public WriteAttribute {
public:
    WriteColorControlWhitePointX()
        : WriteAttribute("white-point-x")
    {
        AddArgument("attr-name", "white-point-x");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlWhitePointX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeWhitePointXWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("ColorControl WhitePointX write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlWhitePointX : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlWhitePointX()
        : SubscribeAttribute("white-point-x")
    {
    }

    ~SubscribeAttributeColorControlWhitePointX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWhitePointXWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.WhitePointX response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WhitePointY
 */
class ReadColorControlWhitePointY : public ReadAttribute {
public:
    ReadColorControlWhitePointY()
        : ReadAttribute("white-point-y")
    {
    }

    ~ReadColorControlWhitePointY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000031) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeWhitePointYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.WhitePointY response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl WhitePointY read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlWhitePointY : public WriteAttribute {
public:
    WriteColorControlWhitePointY()
        : WriteAttribute("white-point-y")
    {
        AddArgument("attr-name", "white-point-y");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlWhitePointY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeWhitePointYWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("ColorControl WhitePointY write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlWhitePointY : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlWhitePointY()
        : SubscribeAttribute("white-point-y")
    {
    }

    ~SubscribeAttributeColorControlWhitePointY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWhitePointYWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.WhitePointY response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointRX
 */
class ReadColorControlColorPointRX : public ReadAttribute {
public:
    ReadColorControlColorPointRX()
        : ReadAttribute("color-point-rx")
    {
    }

    ~ReadColorControlColorPointRX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000032) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointRXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointRX response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointRX read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointRX : public WriteAttribute {
public:
    WriteColorControlColorPointRX()
        : WriteAttribute("color-point-rx")
    {
        AddArgument("attr-name", "color-point-rx");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointRX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeColorPointRXWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("ColorControl ColorPointRX write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlColorPointRX : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointRX()
        : SubscribeAttribute("color-point-rx")
    {
    }

    ~SubscribeAttributeColorControlColorPointRX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointRXWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointRX response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointRY
 */
class ReadColorControlColorPointRY : public ReadAttribute {
public:
    ReadColorControlColorPointRY()
        : ReadAttribute("color-point-ry")
    {
    }

    ~ReadColorControlColorPointRY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000033) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointRYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointRY response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointRY read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointRY : public WriteAttribute {
public:
    WriteColorControlColorPointRY()
        : WriteAttribute("color-point-ry")
    {
        AddArgument("attr-name", "color-point-ry");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointRY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000033) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeColorPointRYWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("ColorControl ColorPointRY write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlColorPointRY : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointRY()
        : SubscribeAttribute("color-point-ry")
    {
    }

    ~SubscribeAttributeColorControlColorPointRY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000033) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointRYWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointRY response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointRIntensity
 */
class ReadColorControlColorPointRIntensity : public ReadAttribute {
public:
    ReadColorControlColorPointRIntensity()
        : ReadAttribute("color-point-rintensity")
    {
    }

    ~ReadColorControlColorPointRIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000034) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointRIntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointRIntensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointRIntensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointRIntensity : public WriteAttribute {
public:
    WriteColorControlColorPointRIntensity()
        : WriteAttribute("color-point-rintensity")
    {
        AddArgument("attr-name", "color-point-rintensity");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointRIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000034) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeColorPointRIntensityWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("ColorControl ColorPointRIntensity write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeColorControlColorPointRIntensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointRIntensity()
        : SubscribeAttribute("color-point-rintensity")
    {
    }

    ~SubscribeAttributeColorControlColorPointRIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000034) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointRIntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointRIntensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointGX
 */
class ReadColorControlColorPointGX : public ReadAttribute {
public:
    ReadColorControlColorPointGX()
        : ReadAttribute("color-point-gx")
    {
    }

    ~ReadColorControlColorPointGX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000036) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointGXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointGX response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointGX read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointGX : public WriteAttribute {
public:
    WriteColorControlColorPointGX()
        : WriteAttribute("color-point-gx")
    {
        AddArgument("attr-name", "color-point-gx");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointGX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000036) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeColorPointGXWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("ColorControl ColorPointGX write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlColorPointGX : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointGX()
        : SubscribeAttribute("color-point-gx")
    {
    }

    ~SubscribeAttributeColorControlColorPointGX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000036) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointGXWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointGX response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointGY
 */
class ReadColorControlColorPointGY : public ReadAttribute {
public:
    ReadColorControlColorPointGY()
        : ReadAttribute("color-point-gy")
    {
    }

    ~ReadColorControlColorPointGY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000037) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointGYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointGY response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointGY read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointGY : public WriteAttribute {
public:
    WriteColorControlColorPointGY()
        : WriteAttribute("color-point-gy")
    {
        AddArgument("attr-name", "color-point-gy");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointGY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000037) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeColorPointGYWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("ColorControl ColorPointGY write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlColorPointGY : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointGY()
        : SubscribeAttribute("color-point-gy")
    {
    }

    ~SubscribeAttributeColorControlColorPointGY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000037) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointGYWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointGY response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointGIntensity
 */
class ReadColorControlColorPointGIntensity : public ReadAttribute {
public:
    ReadColorControlColorPointGIntensity()
        : ReadAttribute("color-point-gintensity")
    {
    }

    ~ReadColorControlColorPointGIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00000038) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointGIntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointGIntensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointGIntensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointGIntensity : public WriteAttribute {
public:
    WriteColorControlColorPointGIntensity()
        : WriteAttribute("color-point-gintensity")
    {
        AddArgument("attr-name", "color-point-gintensity");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointGIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00000038) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeColorPointGIntensityWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("ColorControl ColorPointGIntensity write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeColorControlColorPointGIntensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointGIntensity()
        : SubscribeAttribute("color-point-gintensity")
    {
    }

    ~SubscribeAttributeColorControlColorPointGIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00000038) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointGIntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointGIntensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointBX
 */
class ReadColorControlColorPointBX : public ReadAttribute {
public:
    ReadColorControlColorPointBX()
        : ReadAttribute("color-point-bx")
    {
    }

    ~ReadColorControlColorPointBX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000003A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointBXWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointBX response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointBX read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointBX : public WriteAttribute {
public:
    WriteColorControlColorPointBX()
        : WriteAttribute("color-point-bx")
    {
        AddArgument("attr-name", "color-point-bx");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointBX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x0000003A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeColorPointBXWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("ColorControl ColorPointBX write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlColorPointBX : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointBX()
        : SubscribeAttribute("color-point-bx")
    {
    }

    ~SubscribeAttributeColorControlColorPointBX() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000003A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointBXWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointBX response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointBY
 */
class ReadColorControlColorPointBY : public ReadAttribute {
public:
    ReadColorControlColorPointBY()
        : ReadAttribute("color-point-by")
    {
    }

    ~ReadColorControlColorPointBY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000003B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointBYWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointBY response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointBY read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointBY : public WriteAttribute {
public:
    WriteColorControlColorPointBY()
        : WriteAttribute("color-point-by")
    {
        AddArgument("attr-name", "color-point-by");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointBY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x0000003B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeColorPointBYWithValue:value
                                              params:params
                                          completion:^(NSError * _Nullable error) {
                                              if (error != nil) {
                                                  LogNSError("ColorControl ColorPointBY write Error", error);
                                              }
                                              SetCommandExitStatus(error);
                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlColorPointBY : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointBY()
        : SubscribeAttribute("color-point-by")
    {
    }

    ~SubscribeAttributeColorControlColorPointBY() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000003B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointBYWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointBY response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorPointBIntensity
 */
class ReadColorControlColorPointBIntensity : public ReadAttribute {
public:
    ReadColorControlColorPointBIntensity()
        : ReadAttribute("color-point-bintensity")
    {
    }

    ~ReadColorControlColorPointBIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000003C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorPointBIntensityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorPointBIntensity response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorPointBIntensity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlColorPointBIntensity : public WriteAttribute {
public:
    WriteColorControlColorPointBIntensity()
        : WriteAttribute("color-point-bintensity")
    {
        AddArgument("attr-name", "color-point-bintensity");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlColorPointBIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x0000003C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeColorPointBIntensityWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("ColorControl ColorPointBIntensity write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeColorControlColorPointBIntensity : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorPointBIntensity()
        : SubscribeAttribute("color-point-bintensity")
    {
    }

    ~SubscribeAttributeColorControlColorPointBIntensity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000003C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorPointBIntensityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorPointBIntensity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EnhancedCurrentHue
 */
class ReadColorControlEnhancedCurrentHue : public ReadAttribute {
public:
    ReadColorControlEnhancedCurrentHue()
        : ReadAttribute("enhanced-current-hue")
    {
    }

    ~ReadColorControlEnhancedCurrentHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeEnhancedCurrentHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.EnhancedCurrentHue response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl EnhancedCurrentHue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlEnhancedCurrentHue : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlEnhancedCurrentHue()
        : SubscribeAttribute("enhanced-current-hue")
    {
    }

    ~SubscribeAttributeColorControlEnhancedCurrentHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnhancedCurrentHueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.EnhancedCurrentHue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EnhancedColorMode
 */
class ReadColorControlEnhancedColorMode : public ReadAttribute {
public:
    ReadColorControlEnhancedColorMode()
        : ReadAttribute("enhanced-color-mode")
    {
    }

    ~ReadColorControlEnhancedColorMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeEnhancedColorModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.EnhancedColorMode response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl EnhancedColorMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlEnhancedColorMode : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlEnhancedColorMode()
        : SubscribeAttribute("enhanced-color-mode")
    {
    }

    ~SubscribeAttributeColorControlEnhancedColorMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnhancedColorModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.EnhancedColorMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorLoopActive
 */
class ReadColorControlColorLoopActive : public ReadAttribute {
public:
    ReadColorControlColorLoopActive()
        : ReadAttribute("color-loop-active")
    {
    }

    ~ReadColorControlColorLoopActive() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorLoopActiveWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorLoopActive response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorLoopActive read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorLoopActive : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorLoopActive()
        : SubscribeAttribute("color-loop-active")
    {
    }

    ~SubscribeAttributeColorControlColorLoopActive() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorLoopActiveWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorLoopActive response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorLoopDirection
 */
class ReadColorControlColorLoopDirection : public ReadAttribute {
public:
    ReadColorControlColorLoopDirection()
        : ReadAttribute("color-loop-direction")
    {
    }

    ~ReadColorControlColorLoopDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorLoopDirectionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorLoopDirection response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorLoopDirection read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorLoopDirection : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorLoopDirection()
        : SubscribeAttribute("color-loop-direction")
    {
    }

    ~SubscribeAttributeColorControlColorLoopDirection() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorLoopDirectionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorLoopDirection response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorLoopTime
 */
class ReadColorControlColorLoopTime : public ReadAttribute {
public:
    ReadColorControlColorLoopTime()
        : ReadAttribute("color-loop-time")
    {
    }

    ~ReadColorControlColorLoopTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorLoopTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorLoopTime response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorLoopTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorLoopTime : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorLoopTime()
        : SubscribeAttribute("color-loop-time")
    {
    }

    ~SubscribeAttributeColorControlColorLoopTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorLoopTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorLoopTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorLoopStartEnhancedHue
 */
class ReadColorControlColorLoopStartEnhancedHue : public ReadAttribute {
public:
    ReadColorControlColorLoopStartEnhancedHue()
        : ReadAttribute("color-loop-start-enhanced-hue")
    {
    }

    ~ReadColorControlColorLoopStartEnhancedHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorLoopStartEnhancedHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorLoopStartEnhancedHue response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorLoopStartEnhancedHue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorLoopStartEnhancedHue : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorLoopStartEnhancedHue()
        : SubscribeAttribute("color-loop-start-enhanced-hue")
    {
    }

    ~SubscribeAttributeColorControlColorLoopStartEnhancedHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorLoopStartEnhancedHueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorLoopStartEnhancedHue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorLoopStoredEnhancedHue
 */
class ReadColorControlColorLoopStoredEnhancedHue : public ReadAttribute {
public:
    ReadColorControlColorLoopStoredEnhancedHue()
        : ReadAttribute("color-loop-stored-enhanced-hue")
    {
    }

    ~ReadColorControlColorLoopStoredEnhancedHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorLoopStoredEnhancedHueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorLoopStoredEnhancedHue response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorLoopStoredEnhancedHue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorLoopStoredEnhancedHue : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorLoopStoredEnhancedHue()
        : SubscribeAttribute("color-loop-stored-enhanced-hue")
    {
    }

    ~SubscribeAttributeColorControlColorLoopStoredEnhancedHue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorLoopStoredEnhancedHueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorLoopStoredEnhancedHue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorCapabilities
 */
class ReadColorControlColorCapabilities : public ReadAttribute {
public:
    ReadColorControlColorCapabilities()
        : ReadAttribute("color-capabilities")
    {
    }

    ~ReadColorControlColorCapabilities() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000400A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorCapabilitiesWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorCapabilities response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorCapabilities read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorCapabilities : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorCapabilities()
        : SubscribeAttribute("color-capabilities")
    {
    }

    ~SubscribeAttributeColorControlColorCapabilities() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000400A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorCapabilitiesWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorCapabilities response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorTempPhysicalMinMireds
 */
class ReadColorControlColorTempPhysicalMinMireds : public ReadAttribute {
public:
    ReadColorControlColorTempPhysicalMinMireds()
        : ReadAttribute("color-temp-physical-min-mireds")
    {
    }

    ~ReadColorControlColorTempPhysicalMinMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000400B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorTempPhysicalMinMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorTempPhysicalMinMireds response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorTempPhysicalMinMireds read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorTempPhysicalMinMireds : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorTempPhysicalMinMireds()
        : SubscribeAttribute("color-temp-physical-min-mireds")
    {
    }

    ~SubscribeAttributeColorControlColorTempPhysicalMinMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000400B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorTempPhysicalMinMiredsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorTempPhysicalMinMireds response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ColorTempPhysicalMaxMireds
 */
class ReadColorControlColorTempPhysicalMaxMireds : public ReadAttribute {
public:
    ReadColorControlColorTempPhysicalMaxMireds()
        : ReadAttribute("color-temp-physical-max-mireds")
    {
    }

    ~ReadColorControlColorTempPhysicalMaxMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000400C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeColorTempPhysicalMaxMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ColorTempPhysicalMaxMireds response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ColorTempPhysicalMaxMireds read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlColorTempPhysicalMaxMireds : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlColorTempPhysicalMaxMireds()
        : SubscribeAttribute("color-temp-physical-max-mireds")
    {
    }

    ~SubscribeAttributeColorControlColorTempPhysicalMaxMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000400C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeColorTempPhysicalMaxMiredsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ColorTempPhysicalMaxMireds response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CoupleColorTempToLevelMinMireds
 */
class ReadColorControlCoupleColorTempToLevelMinMireds : public ReadAttribute {
public:
    ReadColorControlCoupleColorTempToLevelMinMireds()
        : ReadAttribute("couple-color-temp-to-level-min-mireds")
    {
    }

    ~ReadColorControlCoupleColorTempToLevelMinMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000400D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster
            readAttributeCoupleColorTempToLevelMinMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.CoupleColorTempToLevelMinMireds response %@", [value description]);
                if (error != nil) {
                    LogNSError("ColorControl CoupleColorTempToLevelMinMireds read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlCoupleColorTempToLevelMinMireds : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlCoupleColorTempToLevelMinMireds()
        : SubscribeAttribute("couple-color-temp-to-level-min-mireds")
    {
    }

    ~SubscribeAttributeColorControlCoupleColorTempToLevelMinMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000400D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCoupleColorTempToLevelMinMiredsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.CoupleColorTempToLevelMinMireds response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StartUpColorTemperatureMireds
 */
class ReadColorControlStartUpColorTemperatureMireds : public ReadAttribute {
public:
    ReadColorControlStartUpColorTemperatureMireds()
        : ReadAttribute("start-up-color-temperature-mireds")
    {
    }

    ~ReadColorControlStartUpColorTemperatureMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x00004010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeStartUpColorTemperatureMiredsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.StartUpColorTemperatureMireds response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl StartUpColorTemperatureMireds read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteColorControlStartUpColorTemperatureMireds : public WriteAttribute {
public:
    WriteColorControlStartUpColorTemperatureMireds()
        : WriteAttribute("start-up-color-temperature-mireds")
    {
        AddArgument("attr-name", "start-up-color-temperature-mireds");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteColorControlStartUpColorTemperatureMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) WriteAttribute (0x00004010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeStartUpColorTemperatureMiredsWithValue:value
                                                          params:params
                                                      completion:^(NSError * _Nullable error) {
                                                          if (error != nil) {
                                                              LogNSError(
                                                                  "ColorControl StartUpColorTemperatureMireds write Error", error);
                                                          }
                                                          SetCommandExitStatus(error);
                                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeColorControlStartUpColorTemperatureMireds : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlStartUpColorTemperatureMireds()
        : SubscribeAttribute("start-up-color-temperature-mireds")
    {
    }

    ~SubscribeAttributeColorControlStartUpColorTemperatureMireds() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x00004010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStartUpColorTemperatureMiredsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.StartUpColorTemperatureMireds response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadColorControlGeneratedCommandList : public ReadAttribute {
public:
    ReadColorControlGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadColorControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeColorControlGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadColorControlAcceptedCommandList : public ReadAttribute {
public:
    ReadColorControlAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadColorControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeColorControlAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadColorControlAttributeList : public ReadAttribute {
public:
    ReadColorControlAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadColorControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeColorControlAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadColorControlFeatureMap : public ReadAttribute {
public:
    ReadColorControlFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadColorControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeColorControlFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadColorControlClusterRevision : public ReadAttribute {
public:
    ReadColorControlClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadColorControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeColorControlClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster BallastConfiguration                                        | 0x0301 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * PhysicalMinLevel                                                  | 0x0000 |
| * PhysicalMaxLevel                                                  | 0x0001 |
| * BallastStatus                                                     | 0x0002 |
| * MinLevel                                                          | 0x0010 |
| * MaxLevel                                                          | 0x0011 |
| * IntrinsicBallastFactor                                            | 0x0014 |
| * BallastFactorAdjustment                                           | 0x0015 |
| * LampQuantity                                                      | 0x0020 |
| * LampType                                                          | 0x0030 |
| * LampManufacturer                                                  | 0x0031 |
| * LampRatedHours                                                    | 0x0032 |
| * LampBurnHours                                                     | 0x0033 |
| * LampAlarmMode                                                     | 0x0034 |
| * LampBurnHoursTripPoint                                            | 0x0035 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute PhysicalMinLevel
 */
class ReadBallastConfigurationPhysicalMinLevel : public ReadAttribute {
public:
    ReadBallastConfigurationPhysicalMinLevel()
        : ReadAttribute("physical-min-level")
    {
    }

    ~ReadBallastConfigurationPhysicalMinLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributePhysicalMinLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.PhysicalMinLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration PhysicalMinLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationPhysicalMinLevel : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationPhysicalMinLevel()
        : SubscribeAttribute("physical-min-level")
    {
    }

    ~SubscribeAttributeBallastConfigurationPhysicalMinLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhysicalMinLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.PhysicalMinLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PhysicalMaxLevel
 */
class ReadBallastConfigurationPhysicalMaxLevel : public ReadAttribute {
public:
    ReadBallastConfigurationPhysicalMaxLevel()
        : ReadAttribute("physical-max-level")
    {
    }

    ~ReadBallastConfigurationPhysicalMaxLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributePhysicalMaxLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.PhysicalMaxLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration PhysicalMaxLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationPhysicalMaxLevel : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationPhysicalMaxLevel()
        : SubscribeAttribute("physical-max-level")
    {
    }

    ~SubscribeAttributeBallastConfigurationPhysicalMaxLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhysicalMaxLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.PhysicalMaxLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BallastStatus
 */
class ReadBallastConfigurationBallastStatus : public ReadAttribute {
public:
    ReadBallastConfigurationBallastStatus()
        : ReadAttribute("ballast-status")
    {
    }

    ~ReadBallastConfigurationBallastStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeBallastStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.BallastStatus response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration BallastStatus read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationBallastStatus : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationBallastStatus()
        : SubscribeAttribute("ballast-status")
    {
    }

    ~SubscribeAttributeBallastConfigurationBallastStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBallastStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.BallastStatus response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinLevel
 */
class ReadBallastConfigurationMinLevel : public ReadAttribute {
public:
    ReadBallastConfigurationMinLevel()
        : ReadAttribute("min-level")
    {
    }

    ~ReadBallastConfigurationMinLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeMinLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.MinLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration MinLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationMinLevel : public WriteAttribute {
public:
    WriteBallastConfigurationMinLevel()
        : WriteAttribute("min-level")
    {
        AddArgument("attr-name", "min-level");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationMinLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeMinLevelWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("BallastConfiguration MinLevel write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeBallastConfigurationMinLevel : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationMinLevel()
        : SubscribeAttribute("min-level")
    {
    }

    ~SubscribeAttributeBallastConfigurationMinLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.MinLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxLevel
 */
class ReadBallastConfigurationMaxLevel : public ReadAttribute {
public:
    ReadBallastConfigurationMaxLevel()
        : ReadAttribute("max-level")
    {
    }

    ~ReadBallastConfigurationMaxLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeMaxLevelWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.MaxLevel response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration MaxLevel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationMaxLevel : public WriteAttribute {
public:
    WriteBallastConfigurationMaxLevel()
        : WriteAttribute("max-level")
    {
        AddArgument("attr-name", "max-level");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationMaxLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeMaxLevelWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("BallastConfiguration MaxLevel write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeBallastConfigurationMaxLevel : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationMaxLevel()
        : SubscribeAttribute("max-level")
    {
    }

    ~SubscribeAttributeBallastConfigurationMaxLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxLevelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.MaxLevel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute IntrinsicBallastFactor
 */
class ReadBallastConfigurationIntrinsicBallastFactor : public ReadAttribute {
public:
    ReadBallastConfigurationIntrinsicBallastFactor()
        : ReadAttribute("intrinsic-ballast-factor")
    {
    }

    ~ReadBallastConfigurationIntrinsicBallastFactor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeIntrinsicBallastFactorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.IntrinsicBallastFactor response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration IntrinsicBallastFactor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationIntrinsicBallastFactor : public WriteAttribute {
public:
    WriteBallastConfigurationIntrinsicBallastFactor()
        : WriteAttribute("intrinsic-ballast-factor")
    {
        AddArgument("attr-name", "intrinsic-ballast-factor");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationIntrinsicBallastFactor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster
            writeAttributeIntrinsicBallastFactorWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("BallastConfiguration IntrinsicBallastFactor write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeBallastConfigurationIntrinsicBallastFactor : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationIntrinsicBallastFactor()
        : SubscribeAttribute("intrinsic-ballast-factor")
    {
    }

    ~SubscribeAttributeBallastConfigurationIntrinsicBallastFactor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeIntrinsicBallastFactorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.IntrinsicBallastFactor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BallastFactorAdjustment
 */
class ReadBallastConfigurationBallastFactorAdjustment : public ReadAttribute {
public:
    ReadBallastConfigurationBallastFactorAdjustment()
        : ReadAttribute("ballast-factor-adjustment")
    {
    }

    ~ReadBallastConfigurationBallastFactorAdjustment() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeBallastFactorAdjustmentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.BallastFactorAdjustment response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration BallastFactorAdjustment read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationBallastFactorAdjustment : public WriteAttribute {
public:
    WriteBallastConfigurationBallastFactorAdjustment()
        : WriteAttribute("ballast-factor-adjustment")
    {
        AddArgument("attr-name", "ballast-factor-adjustment");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationBallastFactorAdjustment() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeBallastFactorAdjustmentWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError(
                                                                 "BallastConfiguration BallastFactorAdjustment write Error", error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeBallastConfigurationBallastFactorAdjustment : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationBallastFactorAdjustment()
        : SubscribeAttribute("ballast-factor-adjustment")
    {
    }

    ~SubscribeAttributeBallastConfigurationBallastFactorAdjustment() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBallastFactorAdjustmentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.BallastFactorAdjustment response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LampQuantity
 */
class ReadBallastConfigurationLampQuantity : public ReadAttribute {
public:
    ReadBallastConfigurationLampQuantity()
        : ReadAttribute("lamp-quantity")
    {
    }

    ~ReadBallastConfigurationLampQuantity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000020) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLampQuantityWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.LampQuantity response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration LampQuantity read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationLampQuantity : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationLampQuantity()
        : SubscribeAttribute("lamp-quantity")
    {
    }

    ~SubscribeAttributeBallastConfigurationLampQuantity() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLampQuantityWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.LampQuantity response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LampType
 */
class ReadBallastConfigurationLampType : public ReadAttribute {
public:
    ReadBallastConfigurationLampType()
        : ReadAttribute("lamp-type")
    {
    }

    ~ReadBallastConfigurationLampType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000030) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLampTypeWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.LampType response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration LampType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationLampType : public WriteAttribute {
public:
    WriteBallastConfigurationLampType()
        : WriteAttribute("lamp-type")
    {
        AddArgument("attr-name", "lamp-type");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationLampType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeLampTypeWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("BallastConfiguration LampType write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBallastConfigurationLampType : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationLampType()
        : SubscribeAttribute("lamp-type")
    {
    }

    ~SubscribeAttributeBallastConfigurationLampType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLampTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.LampType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LampManufacturer
 */
class ReadBallastConfigurationLampManufacturer : public ReadAttribute {
public:
    ReadBallastConfigurationLampManufacturer()
        : ReadAttribute("lamp-manufacturer")
    {
    }

    ~ReadBallastConfigurationLampManufacturer() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000031) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLampManufacturerWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.LampManufacturer response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration LampManufacturer read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationLampManufacturer : public WriteAttribute {
public:
    WriteBallastConfigurationLampManufacturer()
        : WriteAttribute("lamp-manufacturer")
    {
        AddArgument("attr-name", "lamp-manufacturer");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationLampManufacturer() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeLampManufacturerWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("BallastConfiguration LampManufacturer write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeBallastConfigurationLampManufacturer : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationLampManufacturer()
        : SubscribeAttribute("lamp-manufacturer")
    {
    }

    ~SubscribeAttributeBallastConfigurationLampManufacturer() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLampManufacturerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.LampManufacturer response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LampRatedHours
 */
class ReadBallastConfigurationLampRatedHours : public ReadAttribute {
public:
    ReadBallastConfigurationLampRatedHours()
        : ReadAttribute("lamp-rated-hours")
    {
    }

    ~ReadBallastConfigurationLampRatedHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000032) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLampRatedHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.LampRatedHours response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration LampRatedHours read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationLampRatedHours : public WriteAttribute {
public:
    WriteBallastConfigurationLampRatedHours()
        : WriteAttribute("lamp-rated-hours")
    {
        AddArgument("attr-name", "lamp-rated-hours");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationLampRatedHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeLampRatedHoursWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("BallastConfiguration LampRatedHours write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeBallastConfigurationLampRatedHours : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationLampRatedHours()
        : SubscribeAttribute("lamp-rated-hours")
    {
    }

    ~SubscribeAttributeBallastConfigurationLampRatedHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLampRatedHoursWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.LampRatedHours response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LampBurnHours
 */
class ReadBallastConfigurationLampBurnHours : public ReadAttribute {
public:
    ReadBallastConfigurationLampBurnHours()
        : ReadAttribute("lamp-burn-hours")
    {
    }

    ~ReadBallastConfigurationLampBurnHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000033) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLampBurnHoursWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.LampBurnHours response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration LampBurnHours read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationLampBurnHours : public WriteAttribute {
public:
    WriteBallastConfigurationLampBurnHours()
        : WriteAttribute("lamp-burn-hours")
    {
        AddArgument("attr-name", "lamp-burn-hours");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationLampBurnHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000033) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeLampBurnHoursWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("BallastConfiguration LampBurnHours write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeBallastConfigurationLampBurnHours : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationLampBurnHours()
        : SubscribeAttribute("lamp-burn-hours")
    {
    }

    ~SubscribeAttributeBallastConfigurationLampBurnHours() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000033) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLampBurnHoursWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.LampBurnHours response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LampAlarmMode
 */
class ReadBallastConfigurationLampAlarmMode : public ReadAttribute {
public:
    ReadBallastConfigurationLampAlarmMode()
        : ReadAttribute("lamp-alarm-mode")
    {
    }

    ~ReadBallastConfigurationLampAlarmMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000034) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLampAlarmModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.LampAlarmMode response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration LampAlarmMode read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationLampAlarmMode : public WriteAttribute {
public:
    WriteBallastConfigurationLampAlarmMode()
        : WriteAttribute("lamp-alarm-mode")
    {
        AddArgument("attr-name", "lamp-alarm-mode");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationLampAlarmMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000034) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeLampAlarmModeWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("BallastConfiguration LampAlarmMode write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeBallastConfigurationLampAlarmMode : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationLampAlarmMode()
        : SubscribeAttribute("lamp-alarm-mode")
    {
    }

    ~SubscribeAttributeBallastConfigurationLampAlarmMode() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000034) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLampAlarmModeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.LampAlarmMode response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LampBurnHoursTripPoint
 */
class ReadBallastConfigurationLampBurnHoursTripPoint : public ReadAttribute {
public:
    ReadBallastConfigurationLampBurnHoursTripPoint()
        : ReadAttribute("lamp-burn-hours-trip-point")
    {
    }

    ~ReadBallastConfigurationLampBurnHoursTripPoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x00000035) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeLampBurnHoursTripPointWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.LampBurnHoursTripPoint response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration LampBurnHoursTripPoint read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteBallastConfigurationLampBurnHoursTripPoint : public WriteAttribute {
public:
    WriteBallastConfigurationLampBurnHoursTripPoint()
        : WriteAttribute("lamp-burn-hours-trip-point")
    {
        AddArgument("attr-name", "lamp-burn-hours-trip-point");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteBallastConfigurationLampBurnHoursTripPoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) WriteAttribute (0x00000035) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster
            writeAttributeLampBurnHoursTripPointWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("BallastConfiguration LampBurnHoursTripPoint write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeBallastConfigurationLampBurnHoursTripPoint : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationLampBurnHoursTripPoint()
        : SubscribeAttribute("lamp-burn-hours-trip-point")
    {
    }

    ~SubscribeAttributeBallastConfigurationLampBurnHoursTripPoint() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x00000035) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLampBurnHoursTripPointWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.LampBurnHoursTripPoint response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadBallastConfigurationGeneratedCommandList : public ReadAttribute {
public:
    ReadBallastConfigurationGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadBallastConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeBallastConfigurationGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadBallastConfigurationAcceptedCommandList : public ReadAttribute {
public:
    ReadBallastConfigurationAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadBallastConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeBallastConfigurationAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadBallastConfigurationAttributeList : public ReadAttribute {
public:
    ReadBallastConfigurationAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadBallastConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeBallastConfigurationAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadBallastConfigurationFeatureMap : public ReadAttribute {
public:
    ReadBallastConfigurationFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadBallastConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeBallastConfigurationFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadBallastConfigurationClusterRevision : public ReadAttribute {
public:
    ReadBallastConfigurationClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadBallastConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeBallastConfigurationClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device
                                                                                endpointID:@(endpointId)
                                                                                     queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster IlluminanceMeasurement                                      | 0x0400 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MeasuredValue                                                     | 0x0000 |
| * MinMeasuredValue                                                  | 0x0001 |
| * MaxMeasuredValue                                                  | 0x0002 |
| * Tolerance                                                         | 0x0003 |
| * LightSensorType                                                   | 0x0004 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute MeasuredValue
 */
class ReadIlluminanceMeasurementMeasuredValue : public ReadAttribute {
public:
    ReadIlluminanceMeasurementMeasuredValue()
        : ReadAttribute("measured-value")
    {
    }

    ~ReadIlluminanceMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.MeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement MeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementMeasuredValue()
        : SubscribeAttribute("measured-value")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.MeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinMeasuredValue
 */
class ReadIlluminanceMeasurementMinMeasuredValue : public ReadAttribute {
public:
    ReadIlluminanceMeasurementMinMeasuredValue()
        : ReadAttribute("min-measured-value")
    {
    }

    ~ReadIlluminanceMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.MinMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement MinMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementMinMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementMinMeasuredValue()
        : SubscribeAttribute("min-measured-value")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.MinMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxMeasuredValue
 */
class ReadIlluminanceMeasurementMaxMeasuredValue : public ReadAttribute {
public:
    ReadIlluminanceMeasurementMaxMeasuredValue()
        : ReadAttribute("max-measured-value")
    {
    }

    ~ReadIlluminanceMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.MaxMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement MaxMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementMaxMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementMaxMeasuredValue()
        : SubscribeAttribute("max-measured-value")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.MaxMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Tolerance
 */
class ReadIlluminanceMeasurementTolerance : public ReadAttribute {
public:
    ReadIlluminanceMeasurementTolerance()
        : ReadAttribute("tolerance")
    {
    }

    ~ReadIlluminanceMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.Tolerance response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement Tolerance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementTolerance : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementTolerance()
        : SubscribeAttribute("tolerance")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeToleranceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.Tolerance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LightSensorType
 */
class ReadIlluminanceMeasurementLightSensorType : public ReadAttribute {
public:
    ReadIlluminanceMeasurementLightSensorType()
        : ReadAttribute("light-sensor-type")
    {
    }

    ~ReadIlluminanceMeasurementLightSensorType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeLightSensorTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.LightSensorType response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement LightSensorType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementLightSensorType : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementLightSensorType()
        : SubscribeAttribute("light-sensor-type")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementLightSensorType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLightSensorTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.LightSensorType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadIlluminanceMeasurementGeneratedCommandList : public ReadAttribute {
public:
    ReadIlluminanceMeasurementGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadIlluminanceMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadIlluminanceMeasurementAcceptedCommandList : public ReadAttribute {
public:
    ReadIlluminanceMeasurementAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadIlluminanceMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadIlluminanceMeasurementAttributeList : public ReadAttribute {
public:
    ReadIlluminanceMeasurementAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadIlluminanceMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadIlluminanceMeasurementFeatureMap : public ReadAttribute {
public:
    ReadIlluminanceMeasurementFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadIlluminanceMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadIlluminanceMeasurementClusterRevision : public ReadAttribute {
public:
    ReadIlluminanceMeasurementClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadIlluminanceMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster TemperatureMeasurement                                      | 0x0402 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MeasuredValue                                                     | 0x0000 |
| * MinMeasuredValue                                                  | 0x0001 |
| * MaxMeasuredValue                                                  | 0x0002 |
| * Tolerance                                                         | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute MeasuredValue
 */
class ReadTemperatureMeasurementMeasuredValue : public ReadAttribute {
public:
    ReadTemperatureMeasurementMeasuredValue()
        : ReadAttribute("measured-value")
    {
    }

    ~ReadTemperatureMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.MeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement MeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementMeasuredValue()
        : SubscribeAttribute("measured-value")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.MeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinMeasuredValue
 */
class ReadTemperatureMeasurementMinMeasuredValue : public ReadAttribute {
public:
    ReadTemperatureMeasurementMinMeasuredValue()
        : ReadAttribute("min-measured-value")
    {
    }

    ~ReadTemperatureMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.MinMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement MinMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementMinMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementMinMeasuredValue()
        : SubscribeAttribute("min-measured-value")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.MinMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxMeasuredValue
 */
class ReadTemperatureMeasurementMaxMeasuredValue : public ReadAttribute {
public:
    ReadTemperatureMeasurementMaxMeasuredValue()
        : ReadAttribute("max-measured-value")
    {
    }

    ~ReadTemperatureMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.MaxMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement MaxMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementMaxMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementMaxMeasuredValue()
        : SubscribeAttribute("max-measured-value")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.MaxMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Tolerance
 */
class ReadTemperatureMeasurementTolerance : public ReadAttribute {
public:
    ReadTemperatureMeasurementTolerance()
        : ReadAttribute("tolerance")
    {
    }

    ~ReadTemperatureMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.Tolerance response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement Tolerance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementTolerance : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementTolerance()
        : SubscribeAttribute("tolerance")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeToleranceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.Tolerance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadTemperatureMeasurementGeneratedCommandList : public ReadAttribute {
public:
    ReadTemperatureMeasurementGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadTemperatureMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadTemperatureMeasurementAcceptedCommandList : public ReadAttribute {
public:
    ReadTemperatureMeasurementAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadTemperatureMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadTemperatureMeasurementAttributeList : public ReadAttribute {
public:
    ReadTemperatureMeasurementAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadTemperatureMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadTemperatureMeasurementFeatureMap : public ReadAttribute {
public:
    ReadTemperatureMeasurementFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadTemperatureMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadTemperatureMeasurementClusterRevision : public ReadAttribute {
public:
    ReadTemperatureMeasurementClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadTemperatureMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device
                                                                                  endpointID:@(endpointId)
                                                                                       queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster PressureMeasurement                                         | 0x0403 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MeasuredValue                                                     | 0x0000 |
| * MinMeasuredValue                                                  | 0x0001 |
| * MaxMeasuredValue                                                  | 0x0002 |
| * Tolerance                                                         | 0x0003 |
| * ScaledValue                                                       | 0x0010 |
| * MinScaledValue                                                    | 0x0011 |
| * MaxScaledValue                                                    | 0x0012 |
| * ScaledTolerance                                                   | 0x0013 |
| * Scale                                                             | 0x0014 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute MeasuredValue
 */
class ReadPressureMeasurementMeasuredValue : public ReadAttribute {
public:
    ReadPressureMeasurementMeasuredValue()
        : ReadAttribute("measured-value")
    {
    }

    ~ReadPressureMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.MeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement MeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementMeasuredValue()
        : SubscribeAttribute("measured-value")
    {
    }

    ~SubscribeAttributePressureMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.MeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinMeasuredValue
 */
class ReadPressureMeasurementMinMeasuredValue : public ReadAttribute {
public:
    ReadPressureMeasurementMinMeasuredValue()
        : ReadAttribute("min-measured-value")
    {
    }

    ~ReadPressureMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.MinMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement MinMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementMinMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementMinMeasuredValue()
        : SubscribeAttribute("min-measured-value")
    {
    }

    ~SubscribeAttributePressureMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.MinMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxMeasuredValue
 */
class ReadPressureMeasurementMaxMeasuredValue : public ReadAttribute {
public:
    ReadPressureMeasurementMaxMeasuredValue()
        : ReadAttribute("max-measured-value")
    {
    }

    ~ReadPressureMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.MaxMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement MaxMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementMaxMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementMaxMeasuredValue()
        : SubscribeAttribute("max-measured-value")
    {
    }

    ~SubscribeAttributePressureMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.MaxMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Tolerance
 */
class ReadPressureMeasurementTolerance : public ReadAttribute {
public:
    ReadPressureMeasurementTolerance()
        : ReadAttribute("tolerance")
    {
    }

    ~ReadPressureMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.Tolerance response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement Tolerance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementTolerance : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementTolerance()
        : SubscribeAttribute("tolerance")
    {
    }

    ~SubscribeAttributePressureMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeToleranceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.Tolerance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ScaledValue
 */
class ReadPressureMeasurementScaledValue : public ReadAttribute {
public:
    ReadPressureMeasurementScaledValue()
        : ReadAttribute("scaled-value")
    {
    }

    ~ReadPressureMeasurementScaledValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeScaledValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.ScaledValue response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement ScaledValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementScaledValue : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementScaledValue()
        : SubscribeAttribute("scaled-value")
    {
    }

    ~SubscribeAttributePressureMeasurementScaledValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeScaledValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.ScaledValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinScaledValue
 */
class ReadPressureMeasurementMinScaledValue : public ReadAttribute {
public:
    ReadPressureMeasurementMinScaledValue()
        : ReadAttribute("min-scaled-value")
    {
    }

    ~ReadPressureMeasurementMinScaledValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeMinScaledValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.MinScaledValue response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement MinScaledValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementMinScaledValue : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementMinScaledValue()
        : SubscribeAttribute("min-scaled-value")
    {
    }

    ~SubscribeAttributePressureMeasurementMinScaledValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinScaledValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.MinScaledValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxScaledValue
 */
class ReadPressureMeasurementMaxScaledValue : public ReadAttribute {
public:
    ReadPressureMeasurementMaxScaledValue()
        : ReadAttribute("max-scaled-value")
    {
    }

    ~ReadPressureMeasurementMaxScaledValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeMaxScaledValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.MaxScaledValue response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement MaxScaledValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementMaxScaledValue : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementMaxScaledValue()
        : SubscribeAttribute("max-scaled-value")
    {
    }

    ~SubscribeAttributePressureMeasurementMaxScaledValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxScaledValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.MaxScaledValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ScaledTolerance
 */
class ReadPressureMeasurementScaledTolerance : public ReadAttribute {
public:
    ReadPressureMeasurementScaledTolerance()
        : ReadAttribute("scaled-tolerance")
    {
    }

    ~ReadPressureMeasurementScaledTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeScaledToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.ScaledTolerance response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement ScaledTolerance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementScaledTolerance : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementScaledTolerance()
        : SubscribeAttribute("scaled-tolerance")
    {
    }

    ~SubscribeAttributePressureMeasurementScaledTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeScaledToleranceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.ScaledTolerance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Scale
 */
class ReadPressureMeasurementScale : public ReadAttribute {
public:
    ReadPressureMeasurementScale()
        : ReadAttribute("scale")
    {
    }

    ~ReadPressureMeasurementScale() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeScaleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.Scale response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement Scale read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementScale : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementScale()
        : SubscribeAttribute("scale")
    {
    }

    ~SubscribeAttributePressureMeasurementScale() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeScaleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.Scale response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadPressureMeasurementGeneratedCommandList : public ReadAttribute {
public:
    ReadPressureMeasurementGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadPressureMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributePressureMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadPressureMeasurementAcceptedCommandList : public ReadAttribute {
public:
    ReadPressureMeasurementAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadPressureMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributePressureMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadPressureMeasurementAttributeList : public ReadAttribute {
public:
    ReadPressureMeasurementAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadPressureMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributePressureMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadPressureMeasurementFeatureMap : public ReadAttribute {
public:
    ReadPressureMeasurementFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadPressureMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributePressureMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadPressureMeasurementClusterRevision : public ReadAttribute {
public:
    ReadPressureMeasurementClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadPressureMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributePressureMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster FlowMeasurement                                             | 0x0404 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MeasuredValue                                                     | 0x0000 |
| * MinMeasuredValue                                                  | 0x0001 |
| * MaxMeasuredValue                                                  | 0x0002 |
| * Tolerance                                                         | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute MeasuredValue
 */
class ReadFlowMeasurementMeasuredValue : public ReadAttribute {
public:
    ReadFlowMeasurementMeasuredValue()
        : ReadAttribute("measured-value")
    {
    }

    ~ReadFlowMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.MeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement MeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementMeasuredValue()
        : SubscribeAttribute("measured-value")
    {
    }

    ~SubscribeAttributeFlowMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.MeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinMeasuredValue
 */
class ReadFlowMeasurementMinMeasuredValue : public ReadAttribute {
public:
    ReadFlowMeasurementMinMeasuredValue()
        : ReadAttribute("min-measured-value")
    {
    }

    ~ReadFlowMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.MinMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement MinMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementMinMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementMinMeasuredValue()
        : SubscribeAttribute("min-measured-value")
    {
    }

    ~SubscribeAttributeFlowMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.MinMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxMeasuredValue
 */
class ReadFlowMeasurementMaxMeasuredValue : public ReadAttribute {
public:
    ReadFlowMeasurementMaxMeasuredValue()
        : ReadAttribute("max-measured-value")
    {
    }

    ~ReadFlowMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.MaxMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement MaxMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementMaxMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementMaxMeasuredValue()
        : SubscribeAttribute("max-measured-value")
    {
    }

    ~SubscribeAttributeFlowMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.MaxMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Tolerance
 */
class ReadFlowMeasurementTolerance : public ReadAttribute {
public:
    ReadFlowMeasurementTolerance()
        : ReadAttribute("tolerance")
    {
    }

    ~ReadFlowMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.Tolerance response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement Tolerance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementTolerance : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementTolerance()
        : SubscribeAttribute("tolerance")
    {
    }

    ~SubscribeAttributeFlowMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeToleranceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.Tolerance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadFlowMeasurementGeneratedCommandList : public ReadAttribute {
public:
    ReadFlowMeasurementGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadFlowMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeFlowMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadFlowMeasurementAcceptedCommandList : public ReadAttribute {
public:
    ReadFlowMeasurementAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadFlowMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeFlowMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadFlowMeasurementAttributeList : public ReadAttribute {
public:
    ReadFlowMeasurementAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadFlowMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeFlowMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadFlowMeasurementFeatureMap : public ReadAttribute {
public:
    ReadFlowMeasurementFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadFlowMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeFlowMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadFlowMeasurementClusterRevision : public ReadAttribute {
public:
    ReadFlowMeasurementClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadFlowMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeFlowMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster RelativeHumidityMeasurement                                 | 0x0405 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MeasuredValue                                                     | 0x0000 |
| * MinMeasuredValue                                                  | 0x0001 |
| * MaxMeasuredValue                                                  | 0x0002 |
| * Tolerance                                                         | 0x0003 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute MeasuredValue
 */
class ReadRelativeHumidityMeasurementMeasuredValue : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementMeasuredValue()
        : ReadAttribute("measured-value")
    {
    }

    ~ReadRelativeHumidityMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.MeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement MeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementMeasuredValue()
        : SubscribeAttribute("measured-value")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.MeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MinMeasuredValue
 */
class ReadRelativeHumidityMeasurementMinMeasuredValue : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementMinMeasuredValue()
        : ReadAttribute("min-measured-value")
    {
    }

    ~ReadRelativeHumidityMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMinMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.MinMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement MinMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementMinMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementMinMeasuredValue()
        : SubscribeAttribute("min-measured-value")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementMinMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMinMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.MinMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MaxMeasuredValue
 */
class ReadRelativeHumidityMeasurementMaxMeasuredValue : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementMaxMeasuredValue()
        : ReadAttribute("max-measured-value")
    {
    }

    ~ReadRelativeHumidityMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeMaxMeasuredValueWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.MaxMeasuredValue response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement MaxMeasuredValue read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementMaxMeasuredValue : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementMaxMeasuredValue()
        : SubscribeAttribute("max-measured-value")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementMaxMeasuredValue() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMaxMeasuredValueWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.MaxMeasuredValue response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Tolerance
 */
class ReadRelativeHumidityMeasurementTolerance : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementTolerance()
        : ReadAttribute("tolerance")
    {
    }

    ~ReadRelativeHumidityMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeToleranceWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.Tolerance response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement Tolerance read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementTolerance : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementTolerance()
        : SubscribeAttribute("tolerance")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementTolerance() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeToleranceWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.Tolerance response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadRelativeHumidityMeasurementGeneratedCommandList : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadRelativeHumidityMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadRelativeHumidityMeasurementAcceptedCommandList : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadRelativeHumidityMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadRelativeHumidityMeasurementAttributeList : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadRelativeHumidityMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadRelativeHumidityMeasurementFeatureMap : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadRelativeHumidityMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadRelativeHumidityMeasurementClusterRevision : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadRelativeHumidityMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device
                                                                                       endpointID:@(endpointId)
                                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster OccupancySensing                                            | 0x0406 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Occupancy                                                         | 0x0000 |
| * OccupancySensorType                                               | 0x0001 |
| * OccupancySensorTypeBitmap                                         | 0x0002 |
| * PIROccupiedToUnoccupiedDelay                                      | 0x0010 |
| * PIRUnoccupiedToOccupiedDelay                                      | 0x0011 |
| * PIRUnoccupiedToOccupiedThreshold                                  | 0x0012 |
| * UltrasonicOccupiedToUnoccupiedDelay                               | 0x0020 |
| * UltrasonicUnoccupiedToOccupiedDelay                               | 0x0021 |
| * UltrasonicUnoccupiedToOccupiedThreshold                           | 0x0022 |
| * PhysicalContactOccupiedToUnoccupiedDelay                          | 0x0030 |
| * PhysicalContactUnoccupiedToOccupiedDelay                          | 0x0031 |
| * PhysicalContactUnoccupiedToOccupiedThreshold                      | 0x0032 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute Occupancy
 */
class ReadOccupancySensingOccupancy : public ReadAttribute {
public:
    ReadOccupancySensingOccupancy()
        : ReadAttribute("occupancy")
    {
    }

    ~ReadOccupancySensingOccupancy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeOccupancyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.Occupancy response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing Occupancy read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingOccupancy : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingOccupancy()
        : SubscribeAttribute("occupancy")
    {
    }

    ~SubscribeAttributeOccupancySensingOccupancy() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupancyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.Occupancy response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OccupancySensorType
 */
class ReadOccupancySensingOccupancySensorType : public ReadAttribute {
public:
    ReadOccupancySensingOccupancySensorType()
        : ReadAttribute("occupancy-sensor-type")
    {
    }

    ~ReadOccupancySensingOccupancySensorType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeOccupancySensorTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.OccupancySensorType response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing OccupancySensorType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingOccupancySensorType : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingOccupancySensorType()
        : SubscribeAttribute("occupancy-sensor-type")
    {
    }

    ~SubscribeAttributeOccupancySensingOccupancySensorType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupancySensorTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.OccupancySensorType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OccupancySensorTypeBitmap
 */
class ReadOccupancySensingOccupancySensorTypeBitmap : public ReadAttribute {
public:
    ReadOccupancySensingOccupancySensorTypeBitmap()
        : ReadAttribute("occupancy-sensor-type-bitmap")
    {
    }

    ~ReadOccupancySensingOccupancySensorTypeBitmap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeOccupancySensorTypeBitmapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.OccupancySensorTypeBitmap response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing OccupancySensorTypeBitmap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingOccupancySensorTypeBitmap : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingOccupancySensorTypeBitmap()
        : SubscribeAttribute("occupancy-sensor-type-bitmap")
    {
    }

    ~SubscribeAttributeOccupancySensingOccupancySensorTypeBitmap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOccupancySensorTypeBitmapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.OccupancySensorTypeBitmap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PIROccupiedToUnoccupiedDelay
 */
class ReadOccupancySensingPIROccupiedToUnoccupiedDelay : public ReadAttribute {
public:
    ReadOccupancySensingPIROccupiedToUnoccupiedDelay()
        : ReadAttribute("piroccupied-to-unoccupied-delay")
    {
    }

    ~ReadOccupancySensingPIROccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePIROccupiedToUnoccupiedDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.PIROccupiedToUnoccupiedDelay response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing PIROccupiedToUnoccupiedDelay read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingPIROccupiedToUnoccupiedDelay : public WriteAttribute {
public:
    WriteOccupancySensingPIROccupiedToUnoccupiedDelay()
        : WriteAttribute("piroccupied-to-unoccupied-delay")
    {
        AddArgument("attr-name", "piroccupied-to-unoccupied-delay");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingPIROccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributePIROccupiedToUnoccupiedDelayWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("OccupancySensing PIROccupiedToUnoccupiedDelay write Error",
                                                                 error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOccupancySensingPIROccupiedToUnoccupiedDelay : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingPIROccupiedToUnoccupiedDelay()
        : SubscribeAttribute("piroccupied-to-unoccupied-delay")
    {
    }

    ~SubscribeAttributeOccupancySensingPIROccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePIROccupiedToUnoccupiedDelayWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.PIROccupiedToUnoccupiedDelay response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PIRUnoccupiedToOccupiedDelay
 */
class ReadOccupancySensingPIRUnoccupiedToOccupiedDelay : public ReadAttribute {
public:
    ReadOccupancySensingPIRUnoccupiedToOccupiedDelay()
        : ReadAttribute("pirunoccupied-to-occupied-delay")
    {
    }

    ~ReadOccupancySensingPIRUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePIRUnoccupiedToOccupiedDelayWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.PIRUnoccupiedToOccupiedDelay response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing PIRUnoccupiedToOccupiedDelay read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingPIRUnoccupiedToOccupiedDelay : public WriteAttribute {
public:
    WriteOccupancySensingPIRUnoccupiedToOccupiedDelay()
        : WriteAttribute("pirunoccupied-to-occupied-delay")
    {
        AddArgument("attr-name", "pirunoccupied-to-occupied-delay");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingPIRUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributePIRUnoccupiedToOccupiedDelayWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError("OccupancySensing PIRUnoccupiedToOccupiedDelay write Error",
                                                                 error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedDelay : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedDelay()
        : SubscribeAttribute("pirunoccupied-to-occupied-delay")
    {
    }

    ~SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePIRUnoccupiedToOccupiedDelayWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.PIRUnoccupiedToOccupiedDelay response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PIRUnoccupiedToOccupiedThreshold
 */
class ReadOccupancySensingPIRUnoccupiedToOccupiedThreshold : public ReadAttribute {
public:
    ReadOccupancySensingPIRUnoccupiedToOccupiedThreshold()
        : ReadAttribute("pirunoccupied-to-occupied-threshold")
    {
    }

    ~ReadOccupancySensingPIRUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster
            readAttributePIRUnoccupiedToOccupiedThresholdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.PIRUnoccupiedToOccupiedThreshold response %@", [value description]);
                if (error != nil) {
                    LogNSError("OccupancySensing PIRUnoccupiedToOccupiedThreshold read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingPIRUnoccupiedToOccupiedThreshold : public WriteAttribute {
public:
    WriteOccupancySensingPIRUnoccupiedToOccupiedThreshold()
        : WriteAttribute("pirunoccupied-to-occupied-threshold")
    {
        AddArgument("attr-name", "pirunoccupied-to-occupied-threshold");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingPIRUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributePIRUnoccupiedToOccupiedThresholdWithValue:value
                                                                  params:params
                                                              completion:^(NSError * _Nullable error) {
                                                                  if (error != nil) {
                                                                      LogNSError("OccupancySensing "
                                                                                 "PIRUnoccupiedToOccupiedThreshold write Error",
                                                                          error);
                                                                  }
                                                                  SetCommandExitStatus(error);
                                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedThreshold : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedThreshold()
        : SubscribeAttribute("pirunoccupied-to-occupied-threshold")
    {
    }

    ~SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePIRUnoccupiedToOccupiedThresholdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.PIRUnoccupiedToOccupiedThreshold response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UltrasonicOccupiedToUnoccupiedDelay
 */
class ReadOccupancySensingUltrasonicOccupiedToUnoccupiedDelay : public ReadAttribute {
public:
    ReadOccupancySensingUltrasonicOccupiedToUnoccupiedDelay()
        : ReadAttribute("ultrasonic-occupied-to-unoccupied-delay")
    {
    }

    ~ReadOccupancySensingUltrasonicOccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000020) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeUltrasonicOccupiedToUnoccupiedDelayWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.UltrasonicOccupiedToUnoccupiedDelay response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing UltrasonicOccupiedToUnoccupiedDelay read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingUltrasonicOccupiedToUnoccupiedDelay : public WriteAttribute {
public:
    WriteOccupancySensingUltrasonicOccupiedToUnoccupiedDelay()
        : WriteAttribute("ultrasonic-occupied-to-unoccupied-delay")
    {
        AddArgument("attr-name", "ultrasonic-occupied-to-unoccupied-delay");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingUltrasonicOccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:value
                                                                params:params
                                                            completion:^(NSError * _Nullable error) {
                                                                if (error != nil) {
                                                                    LogNSError("OccupancySensing "
                                                                               "UltrasonicOccupiedToUnoccupiedDelay write Error",
                                                                        error);
                                                                }
                                                                SetCommandExitStatus(error);
                                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOccupancySensingUltrasonicOccupiedToUnoccupiedDelay : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingUltrasonicOccupiedToUnoccupiedDelay()
        : SubscribeAttribute("ultrasonic-occupied-to-unoccupied-delay")
    {
    }

    ~SubscribeAttributeOccupancySensingUltrasonicOccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUltrasonicOccupiedToUnoccupiedDelayWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.UltrasonicOccupiedToUnoccupiedDelay response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UltrasonicUnoccupiedToOccupiedDelay
 */
class ReadOccupancySensingUltrasonicUnoccupiedToOccupiedDelay : public ReadAttribute {
public:
    ReadOccupancySensingUltrasonicUnoccupiedToOccupiedDelay()
        : ReadAttribute("ultrasonic-unoccupied-to-occupied-delay")
    {
    }

    ~ReadOccupancySensingUltrasonicUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000021) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeUltrasonicUnoccupiedToOccupiedDelayWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.UltrasonicUnoccupiedToOccupiedDelay response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing UltrasonicUnoccupiedToOccupiedDelay read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingUltrasonicUnoccupiedToOccupiedDelay : public WriteAttribute {
public:
    WriteOccupancySensingUltrasonicUnoccupiedToOccupiedDelay()
        : WriteAttribute("ultrasonic-unoccupied-to-occupied-delay")
    {
        AddArgument("attr-name", "ultrasonic-unoccupied-to-occupied-delay");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingUltrasonicUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:value
                                                                params:params
                                                            completion:^(NSError * _Nullable error) {
                                                                if (error != nil) {
                                                                    LogNSError("OccupancySensing "
                                                                               "UltrasonicUnoccupiedToOccupiedDelay write Error",
                                                                        error);
                                                                }
                                                                SetCommandExitStatus(error);
                                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedDelay : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedDelay()
        : SubscribeAttribute("ultrasonic-unoccupied-to-occupied-delay")
    {
    }

    ~SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUltrasonicUnoccupiedToOccupiedDelayWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.UltrasonicUnoccupiedToOccupiedDelay response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute UltrasonicUnoccupiedToOccupiedThreshold
 */
class ReadOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold : public ReadAttribute {
public:
    ReadOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold()
        : ReadAttribute("ultrasonic-unoccupied-to-occupied-threshold")
    {
    }

    ~ReadOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000022) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.UltrasonicUnoccupiedToOccupiedThreshold response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing UltrasonicUnoccupiedToOccupiedThreshold read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold : public WriteAttribute {
public:
    WriteOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold()
        : WriteAttribute("ultrasonic-unoccupied-to-occupied-threshold")
    {
        AddArgument("attr-name", "ultrasonic-unoccupied-to-occupied-threshold");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster
            writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:value
                                                                    params:params
                                                                completion:^(NSError * _Nullable error) {
                                                                    if (error != nil) {
                                                                        LogNSError(
                                                                            "OccupancySensing "
                                                                            "UltrasonicUnoccupiedToOccupiedThreshold write Error",
                                                                            error);
                                                                    }
                                                                    SetCommandExitStatus(error);
                                                                }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold()
        : SubscribeAttribute("ultrasonic-unoccupied-to-occupied-threshold")
    {
    }

    ~SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.UltrasonicUnoccupiedToOccupiedThreshold response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PhysicalContactOccupiedToUnoccupiedDelay
 */
class ReadOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay : public ReadAttribute {
public:
    ReadOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay()
        : ReadAttribute("physical-contact-occupied-to-unoccupied-delay")
    {
    }

    ~ReadOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000030) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePhysicalContactOccupiedToUnoccupiedDelayWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.PhysicalContactOccupiedToUnoccupiedDelay response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing PhysicalContactOccupiedToUnoccupiedDelay read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay : public WriteAttribute {
public:
    WriteOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay()
        : WriteAttribute("physical-contact-occupied-to-unoccupied-delay")
    {
        AddArgument("attr-name", "physical-contact-occupied-to-unoccupied-delay");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:value
                                                                     params:params
                                                                 completion:^(NSError * _Nullable error) {
                                                                     if (error != nil) {
                                                                         LogNSError(
                                                                             "OccupancySensing "
                                                                             "PhysicalContactOccupiedToUnoccupiedDelay write Error",
                                                                             error);
                                                                     }
                                                                     SetCommandExitStatus(error);
                                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay()
        : SubscribeAttribute("physical-contact-occupied-to-unoccupied-delay")
    {
    }

    ~SubscribeAttributeOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhysicalContactOccupiedToUnoccupiedDelayWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.PhysicalContactOccupiedToUnoccupiedDelay response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PhysicalContactUnoccupiedToOccupiedDelay
 */
class ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay : public ReadAttribute {
public:
    ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay()
        : ReadAttribute("physical-contact-unoccupied-to-occupied-delay")
    {
    }

    ~ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000031) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePhysicalContactUnoccupiedToOccupiedDelayWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.PhysicalContactUnoccupiedToOccupiedDelay response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing PhysicalContactUnoccupiedToOccupiedDelay read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay : public WriteAttribute {
public:
    WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay()
        : WriteAttribute("physical-contact-unoccupied-to-occupied-delay")
    {
        AddArgument("attr-name", "physical-contact-unoccupied-to-occupied-delay");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:value
                                                                     params:params
                                                                 completion:^(NSError * _Nullable error) {
                                                                     if (error != nil) {
                                                                         LogNSError(
                                                                             "OccupancySensing "
                                                                             "PhysicalContactUnoccupiedToOccupiedDelay write Error",
                                                                             error);
                                                                     }
                                                                     SetCommandExitStatus(error);
                                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay()
        : SubscribeAttribute("physical-contact-unoccupied-to-occupied-delay")
    {
    }

    ~SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhysicalContactUnoccupiedToOccupiedDelayWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.PhysicalContactUnoccupiedToOccupiedDelay response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PhysicalContactUnoccupiedToOccupiedThreshold
 */
class ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold : public ReadAttribute {
public:
    ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold()
        : ReadAttribute("physical-contact-unoccupied-to-occupied-threshold")
    {
    }

    ~ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x00000032) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.PhysicalContactUnoccupiedToOccupiedThreshold response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing PhysicalContactUnoccupiedToOccupiedThreshold read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold : public WriteAttribute {
public:
    WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold()
        : WriteAttribute("physical-contact-unoccupied-to-occupied-threshold")
    {
        AddArgument("attr-name", "physical-contact-unoccupied-to-occupied-threshold");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) WriteAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:value
                                                                              params:params
                                                                          completion:^(NSError * _Nullable error) {
                                                                              if (error != nil) {
                                                                                  LogNSError("OccupancySensing "
                                                                                             "PhysicalContactUnoccupiedToOccupiedTh"
                                                                                             "reshold write Error",
                                                                                      error);
                                                                              }
                                                                              SetCommandExitStatus(error);
                                                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold()
        : SubscribeAttribute("physical-contact-unoccupied-to-occupied-threshold")
    {
    }

    ~SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.PhysicalContactUnoccupiedToOccupiedThreshold response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadOccupancySensingGeneratedCommandList : public ReadAttribute {
public:
    ReadOccupancySensingGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadOccupancySensingGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeOccupancySensingGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadOccupancySensingAcceptedCommandList : public ReadAttribute {
public:
    ReadOccupancySensingAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadOccupancySensingAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeOccupancySensingAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadOccupancySensingAttributeList : public ReadAttribute {
public:
    ReadOccupancySensingAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadOccupancySensingAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeOccupancySensingAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadOccupancySensingFeatureMap : public ReadAttribute {
public:
    ReadOccupancySensingFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadOccupancySensingFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeOccupancySensingFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadOccupancySensingClusterRevision : public ReadAttribute {
public:
    ReadOccupancySensingClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadOccupancySensingClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeOccupancySensingClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster WakeOnLan                                                   | 0x0503 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MACAddress                                                        | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute MACAddress
 */
class ReadWakeOnLanMACAddress : public ReadAttribute {
public:
    ReadWakeOnLanMACAddress()
        : ReadAttribute("macaddress")
    {
    }

    ~ReadWakeOnLanMACAddress() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeMACAddressWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WakeOnLAN.MACAddress response %@", [value description]);
            if (error != nil) {
                LogNSError("WakeOnLAN MACAddress read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWakeOnLanMACAddress : public SubscribeAttribute {
public:
    SubscribeAttributeWakeOnLanMACAddress()
        : SubscribeAttribute("macaddress")
    {
    }

    ~SubscribeAttributeWakeOnLanMACAddress() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMACAddressWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WakeOnLAN.MACAddress response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadWakeOnLanGeneratedCommandList : public ReadAttribute {
public:
    ReadWakeOnLanGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadWakeOnLanGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WakeOnLAN.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WakeOnLAN GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWakeOnLanGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWakeOnLanGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeWakeOnLanGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WakeOnLAN.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadWakeOnLanAcceptedCommandList : public ReadAttribute {
public:
    ReadWakeOnLanAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadWakeOnLanAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WakeOnLAN.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("WakeOnLAN AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWakeOnLanAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeWakeOnLanAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeWakeOnLanAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WakeOnLAN.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadWakeOnLanAttributeList : public ReadAttribute {
public:
    ReadWakeOnLanAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadWakeOnLanAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WakeOnLAN.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("WakeOnLAN AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWakeOnLanAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeWakeOnLanAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeWakeOnLanAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WakeOnLAN.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadWakeOnLanFeatureMap : public ReadAttribute {
public:
    ReadWakeOnLanFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadWakeOnLanFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WakeOnLAN.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("WakeOnLAN FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWakeOnLanFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeWakeOnLanFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeWakeOnLanFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WakeOnLAN.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadWakeOnLanClusterRevision : public ReadAttribute {
public:
    ReadWakeOnLanClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadWakeOnLanClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WakeOnLAN.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("WakeOnLAN ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWakeOnLanClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeWakeOnLanClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeWakeOnLanClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device
                                                                     endpointID:@(endpointId)
                                                                          queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WakeOnLAN.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster Channel                                                     | 0x0504 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * ChangeChannel                                                     |   0x00 |
| * ChangeChannelByNumber                                             |   0x02 |
| * SkipChannel                                                       |   0x03 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * ChannelList                                                       | 0x0000 |
| * Lineup                                                            | 0x0001 |
| * CurrentChannel                                                    | 0x0002 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command ChangeChannel
 */
class ChannelChangeChannel : public ClusterCommand {
public:
    ChannelChangeChannel()
        : ClusterCommand("change-channel")
    {
        AddArgument("Match", &mRequest.match);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRChannelClusterChangeChannelParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.match = [[NSString alloc] initWithBytes:mRequest.match.data()
                                                length:mRequest.match.size()
                                              encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster changeChannelWithParams:params
                                  completion:^(
                                      MTRChannelClusterChangeChannelResponseParams * _Nullable values, NSError * _Nullable error) {
                                      NSLog(@"Values: %@", values);
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Channel::Commands::ChangeChannel::Type mRequest;
};

/*
 * Command ChangeChannelByNumber
 */
class ChannelChangeChannelByNumber : public ClusterCommand {
public:
    ChannelChangeChannelByNumber()
        : ClusterCommand("change-channel-by-number")
    {
        AddArgument("MajorNumber", 0, UINT16_MAX, &mRequest.majorNumber);
        AddArgument("MinorNumber", 0, UINT16_MAX, &mRequest.minorNumber);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRChannelClusterChangeChannelByNumberParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.majorNumber = [NSNumber numberWithUnsignedShort:mRequest.majorNumber];
        params.minorNumber = [NSNumber numberWithUnsignedShort:mRequest.minorNumber];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster changeChannelByNumberWithParams:params
                                          completion:^(NSError * _Nullable error) {
                                              responsesNeeded--;
                                              if (error != nil) {
                                                  mError = error;
                                                  LogNSError("Error", error);
                                              }
                                              if (responsesNeeded == 0) {
                                                  SetCommandExitStatus(mError);
                                              }
                                          }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Channel::Commands::ChangeChannelByNumber::Type mRequest;
};

/*
 * Command SkipChannel
 */
class ChannelSkipChannel : public ClusterCommand {
public:
    ChannelSkipChannel()
        : ClusterCommand("skip-channel")
    {
        AddArgument("Count", 0, UINT16_MAX, &mRequest.count);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRChannelClusterSkipChannelParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.count = [NSNumber numberWithUnsignedShort:mRequest.count];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster skipChannelWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::Channel::Commands::SkipChannel::Type mRequest;
};

/*
 * Attribute ChannelList
 */
class ReadChannelChannelList : public ReadAttribute {
public:
    ReadChannelChannelList()
        : ReadAttribute("channel-list")
    {
    }

    ~ReadChannelChannelList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeChannelListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.ChannelList response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel ChannelList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelChannelList : public SubscribeAttribute {
public:
    SubscribeAttributeChannelChannelList()
        : SubscribeAttribute("channel-list")
    {
    }

    ~SubscribeAttributeChannelChannelList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeChannelListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.ChannelList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Lineup
 */
class ReadChannelLineup : public ReadAttribute {
public:
    ReadChannelLineup()
        : ReadAttribute("lineup")
    {
    }

    ~ReadChannelLineup() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster
            readAttributeLineupWithCompletion:^(MTRChannelClusterLineupInfoStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.Lineup response %@", [value description]);
                if (error != nil) {
                    LogNSError("Channel Lineup read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelLineup : public SubscribeAttribute {
public:
    SubscribeAttributeChannelLineup()
        : SubscribeAttribute("lineup")
    {
    }

    ~SubscribeAttributeChannelLineup() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLineupWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRChannelClusterLineupInfoStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.Lineup response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentChannel
 */
class ReadChannelCurrentChannel : public ReadAttribute {
public:
    ReadChannelCurrentChannel()
        : ReadAttribute("current-channel")
    {
    }

    ~ReadChannelCurrentChannel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeCurrentChannelWithCompletion:^(
            MTRChannelClusterChannelInfoStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.CurrentChannel response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel CurrentChannel read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelCurrentChannel : public SubscribeAttribute {
public:
    SubscribeAttributeChannelCurrentChannel()
        : SubscribeAttribute("current-channel")
    {
    }

    ~SubscribeAttributeChannelCurrentChannel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentChannelWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRChannelClusterChannelInfoStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.CurrentChannel response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadChannelGeneratedCommandList : public ReadAttribute {
public:
    ReadChannelGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadChannelGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeChannelGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeChannelGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadChannelAcceptedCommandList : public ReadAttribute {
public:
    ReadChannelAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadChannelAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeChannelAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeChannelAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadChannelAttributeList : public ReadAttribute {
public:
    ReadChannelAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadChannelAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeChannelAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeChannelAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadChannelFeatureMap : public ReadAttribute {
public:
    ReadChannelFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadChannelFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeChannelFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeChannelFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadChannelClusterRevision : public ReadAttribute {
public:
    ReadChannelClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadChannelClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeChannelClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeChannelClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster TargetNavigator                                             | 0x0505 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * NavigateTarget                                                    |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * TargetList                                                        | 0x0000 |
| * CurrentTarget                                                     | 0x0001 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command NavigateTarget
 */
class TargetNavigatorNavigateTarget : public ClusterCommand {
public:
    TargetNavigatorNavigateTarget()
        : ClusterCommand("navigate-target")
    {
        AddArgument("Target", 0, UINT8_MAX, &mRequest.target);
        AddArgument("Data", &mRequest.data);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRTargetNavigatorClusterNavigateTargetParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.target = [NSNumber numberWithUnsignedChar:mRequest.target];
        if (mRequest.data.HasValue()) {
            params.data = [[NSString alloc] initWithBytes:mRequest.data.Value().data()
                                                   length:mRequest.data.Value().size()
                                                 encoding:NSUTF8StringEncoding];
        } else {
            params.data = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster navigateTargetWithParams:params
                                   completion:^(MTRTargetNavigatorClusterNavigateTargetResponseParams * _Nullable values,
                                       NSError * _Nullable error) {
                                       NSLog(@"Values: %@", values);
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::TargetNavigator::Commands::NavigateTarget::Type mRequest;
};

/*
 * Attribute TargetList
 */
class ReadTargetNavigatorTargetList : public ReadAttribute {
public:
    ReadTargetNavigatorTargetList()
        : ReadAttribute("target-list")
    {
    }

    ~ReadTargetNavigatorTargetList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeTargetListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.TargetList response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator TargetList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorTargetList : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorTargetList()
        : SubscribeAttribute("target-list")
    {
    }

    ~SubscribeAttributeTargetNavigatorTargetList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTargetListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.TargetList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentTarget
 */
class ReadTargetNavigatorCurrentTarget : public ReadAttribute {
public:
    ReadTargetNavigatorCurrentTarget()
        : ReadAttribute("current-target")
    {
    }

    ~ReadTargetNavigatorCurrentTarget() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeCurrentTargetWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.CurrentTarget response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator CurrentTarget read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorCurrentTarget : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorCurrentTarget()
        : SubscribeAttribute("current-target")
    {
    }

    ~SubscribeAttributeTargetNavigatorCurrentTarget() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentTargetWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.CurrentTarget response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadTargetNavigatorGeneratedCommandList : public ReadAttribute {
public:
    ReadTargetNavigatorGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadTargetNavigatorGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeTargetNavigatorGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadTargetNavigatorAcceptedCommandList : public ReadAttribute {
public:
    ReadTargetNavigatorAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadTargetNavigatorAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeTargetNavigatorAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadTargetNavigatorAttributeList : public ReadAttribute {
public:
    ReadTargetNavigatorAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadTargetNavigatorAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeTargetNavigatorAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadTargetNavigatorFeatureMap : public ReadAttribute {
public:
    ReadTargetNavigatorFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadTargetNavigatorFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeTargetNavigatorFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadTargetNavigatorClusterRevision : public ReadAttribute {
public:
    ReadTargetNavigatorClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadTargetNavigatorClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeTargetNavigatorClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster MediaPlayback                                               | 0x0506 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * Play                                                              |   0x00 |
| * Pause                                                             |   0x01 |
| * Stop                                                              |   0x02 |
| * StartOver                                                         |   0x03 |
| * Previous                                                          |   0x04 |
| * Next                                                              |   0x05 |
| * Rewind                                                            |   0x06 |
| * FastForward                                                       |   0x07 |
| * SkipForward                                                       |   0x08 |
| * SkipBackward                                                      |   0x09 |
| * Seek                                                              |   0x0B |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * CurrentState                                                      | 0x0000 |
| * StartTime                                                         | 0x0001 |
| * Duration                                                          | 0x0002 |
| * SampledPosition                                                   | 0x0003 |
| * PlaybackSpeed                                                     | 0x0004 |
| * SeekRangeEnd                                                      | 0x0005 |
| * SeekRangeStart                                                    | 0x0006 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command Play
 */
class MediaPlaybackPlay : public ClusterCommand {
public:
    MediaPlaybackPlay()
        : ClusterCommand("play")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterPlayParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster playWithParams:params
                         completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                             NSLog(@"Values: %@", values);
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command Pause
 */
class MediaPlaybackPause : public ClusterCommand {
public:
    MediaPlaybackPause()
        : ClusterCommand("pause")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterPauseParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                pauseWithParams:params
                     completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                         NSLog(@"Values: %@", values);
                         responsesNeeded--;
                         if (error != nil) {
                             mError = error;
                             LogNSError("Error", error);
                         }
                         if (responsesNeeded == 0) {
                             SetCommandExitStatus(mError);
                         }
                     }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command Stop
 */
class MediaPlaybackStop : public ClusterCommand {
public:
    MediaPlaybackStop()
        : ClusterCommand("stop")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterStopParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stopWithParams:params
                         completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                             NSLog(@"Values: %@", values);
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command StartOver
 */
class MediaPlaybackStartOver : public ClusterCommand {
public:
    MediaPlaybackStartOver()
        : ClusterCommand("start-over")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterStartOverParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                startOverWithParams:params
                         completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                             NSLog(@"Values: %@", values);
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command Previous
 */
class MediaPlaybackPrevious : public ClusterCommand {
public:
    MediaPlaybackPrevious()
        : ClusterCommand("previous")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterPreviousParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                previousWithParams:params
                        completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                            NSLog(@"Values: %@", values);
                            responsesNeeded--;
                            if (error != nil) {
                                mError = error;
                                LogNSError("Error", error);
                            }
                            if (responsesNeeded == 0) {
                                SetCommandExitStatus(mError);
                            }
                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command Next
 */
class MediaPlaybackNext : public ClusterCommand {
public:
    MediaPlaybackNext()
        : ClusterCommand("next")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterNextParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster nextWithParams:params
                         completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                             NSLog(@"Values: %@", values);
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command Rewind
 */
class MediaPlaybackRewind : public ClusterCommand {
public:
    MediaPlaybackRewind()
        : ClusterCommand("rewind")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterRewindParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                rewindWithParams:params
                      completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                          NSLog(@"Values: %@", values);
                          responsesNeeded--;
                          if (error != nil) {
                              mError = error;
                              LogNSError("Error", error);
                          }
                          if (responsesNeeded == 0) {
                              SetCommandExitStatus(mError);
                          }
                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command FastForward
 */
class MediaPlaybackFastForward : public ClusterCommand {
public:
    MediaPlaybackFastForward()
        : ClusterCommand("fast-forward")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterFastForwardParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster fastForwardWithParams:params
                                completion:^(
                                    MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                                    NSLog(@"Values: %@", values);
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command SkipForward
 */
class MediaPlaybackSkipForward : public ClusterCommand {
public:
    MediaPlaybackSkipForward()
        : ClusterCommand("skip-forward")
    {
        AddArgument("DeltaPositionMilliseconds", 0, UINT64_MAX, &mRequest.deltaPositionMilliseconds);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterSkipForwardParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.deltaPositionMilliseconds = [NSNumber numberWithUnsignedLongLong:mRequest.deltaPositionMilliseconds];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster skipForwardWithParams:params
                                completion:^(
                                    MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                                    NSLog(@"Values: %@", values);
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::MediaPlayback::Commands::SkipForward::Type mRequest;
};

/*
 * Command SkipBackward
 */
class MediaPlaybackSkipBackward : public ClusterCommand {
public:
    MediaPlaybackSkipBackward()
        : ClusterCommand("skip-backward")
    {
        AddArgument("DeltaPositionMilliseconds", 0, UINT64_MAX, &mRequest.deltaPositionMilliseconds);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterSkipBackwardParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.deltaPositionMilliseconds = [NSNumber numberWithUnsignedLongLong:mRequest.deltaPositionMilliseconds];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster skipBackwardWithParams:params
                                 completion:^(
                                     MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                                     NSLog(@"Values: %@", values);
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::MediaPlayback::Commands::SkipBackward::Type mRequest;
};

/*
 * Command Seek
 */
class MediaPlaybackSeek : public ClusterCommand {
public:
    MediaPlaybackSeek()
        : ClusterCommand("seek")
    {
        AddArgument("Position", 0, UINT64_MAX, &mRequest.position);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) command (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRMediaPlaybackClusterSeekParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.position = [NSNumber numberWithUnsignedLongLong:mRequest.position];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster seekWithParams:params
                         completion:^(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable values, NSError * _Nullable error) {
                             NSLog(@"Values: %@", values);
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::MediaPlayback::Commands::Seek::Type mRequest;
};

/*
 * Attribute CurrentState
 */
class ReadMediaPlaybackCurrentState : public ReadAttribute {
public:
    ReadMediaPlaybackCurrentState()
        : ReadAttribute("current-state")
    {
    }

    ~ReadMediaPlaybackCurrentState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeCurrentStateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.CurrentState response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback CurrentState read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackCurrentState : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackCurrentState()
        : SubscribeAttribute("current-state")
    {
    }

    ~SubscribeAttributeMediaPlaybackCurrentState() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentStateWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.CurrentState response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StartTime
 */
class ReadMediaPlaybackStartTime : public ReadAttribute {
public:
    ReadMediaPlaybackStartTime()
        : ReadAttribute("start-time")
    {
    }

    ~ReadMediaPlaybackStartTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeStartTimeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.StartTime response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback StartTime read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackStartTime : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackStartTime()
        : SubscribeAttribute("start-time")
    {
    }

    ~SubscribeAttributeMediaPlaybackStartTime() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStartTimeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.StartTime response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Duration
 */
class ReadMediaPlaybackDuration : public ReadAttribute {
public:
    ReadMediaPlaybackDuration()
        : ReadAttribute("duration")
    {
    }

    ~ReadMediaPlaybackDuration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeDurationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.Duration response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback Duration read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackDuration : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackDuration()
        : SubscribeAttribute("duration")
    {
    }

    ~SubscribeAttributeMediaPlaybackDuration() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDurationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.Duration response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SampledPosition
 */
class ReadMediaPlaybackSampledPosition : public ReadAttribute {
public:
    ReadMediaPlaybackSampledPosition()
        : ReadAttribute("sampled-position")
    {
    }

    ~ReadMediaPlaybackSampledPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeSampledPositionWithCompletion:^(
            MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.SampledPosition response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback SampledPosition read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackSampledPosition : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackSampledPosition()
        : SubscribeAttribute("sampled-position")
    {
    }

    ~SubscribeAttributeMediaPlaybackSampledPosition() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSampledPositionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRMediaPlaybackClusterPlaybackPositionStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.SampledPosition response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PlaybackSpeed
 */
class ReadMediaPlaybackPlaybackSpeed : public ReadAttribute {
public:
    ReadMediaPlaybackPlaybackSpeed()
        : ReadAttribute("playback-speed")
    {
    }

    ~ReadMediaPlaybackPlaybackSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributePlaybackSpeedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.PlaybackSpeed response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback PlaybackSpeed read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackPlaybackSpeed : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackPlaybackSpeed()
        : SubscribeAttribute("playback-speed")
    {
    }

    ~SubscribeAttributeMediaPlaybackPlaybackSpeed() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePlaybackSpeedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.PlaybackSpeed response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SeekRangeEnd
 */
class ReadMediaPlaybackSeekRangeEnd : public ReadAttribute {
public:
    ReadMediaPlaybackSeekRangeEnd()
        : ReadAttribute("seek-range-end")
    {
    }

    ~ReadMediaPlaybackSeekRangeEnd() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeSeekRangeEndWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.SeekRangeEnd response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback SeekRangeEnd read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackSeekRangeEnd : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackSeekRangeEnd()
        : SubscribeAttribute("seek-range-end")
    {
    }

    ~SubscribeAttributeMediaPlaybackSeekRangeEnd() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSeekRangeEndWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.SeekRangeEnd response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SeekRangeStart
 */
class ReadMediaPlaybackSeekRangeStart : public ReadAttribute {
public:
    ReadMediaPlaybackSeekRangeStart()
        : ReadAttribute("seek-range-start")
    {
    }

    ~ReadMediaPlaybackSeekRangeStart() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeSeekRangeStartWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.SeekRangeStart response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback SeekRangeStart read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackSeekRangeStart : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackSeekRangeStart()
        : SubscribeAttribute("seek-range-start")
    {
    }

    ~SubscribeAttributeMediaPlaybackSeekRangeStart() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSeekRangeStartWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.SeekRangeStart response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadMediaPlaybackGeneratedCommandList : public ReadAttribute {
public:
    ReadMediaPlaybackGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadMediaPlaybackGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeMediaPlaybackGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadMediaPlaybackAcceptedCommandList : public ReadAttribute {
public:
    ReadMediaPlaybackAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadMediaPlaybackAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeMediaPlaybackAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadMediaPlaybackAttributeList : public ReadAttribute {
public:
    ReadMediaPlaybackAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadMediaPlaybackAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeMediaPlaybackAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadMediaPlaybackFeatureMap : public ReadAttribute {
public:
    ReadMediaPlaybackFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadMediaPlaybackFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeMediaPlaybackFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadMediaPlaybackClusterRevision : public ReadAttribute {
public:
    ReadMediaPlaybackClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadMediaPlaybackClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeMediaPlaybackClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device
                                                                         endpointID:@(endpointId)
                                                                              queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster MediaInput                                                  | 0x0507 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * SelectInput                                                       |   0x00 |
| * ShowInputStatus                                                   |   0x01 |
| * HideInputStatus                                                   |   0x02 |
| * RenameInput                                                       |   0x03 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * InputList                                                         | 0x0000 |
| * CurrentInput                                                      | 0x0001 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command SelectInput
 */
class MediaInputSelectInput : public ClusterCommand {
public:
    MediaInputSelectInput()
        : ClusterCommand("select-input")
    {
        AddArgument("Index", 0, UINT8_MAX, &mRequest.index);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRMediaInputClusterSelectInputParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.index = [NSNumber numberWithUnsignedChar:mRequest.index];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster selectInputWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::MediaInput::Commands::SelectInput::Type mRequest;
};

/*
 * Command ShowInputStatus
 */
class MediaInputShowInputStatus : public ClusterCommand {
public:
    MediaInputShowInputStatus()
        : ClusterCommand("show-input-status")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRMediaInputClusterShowInputStatusParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster showInputStatusWithParams:params
                                    completion:^(NSError * _Nullable error) {
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command HideInputStatus
 */
class MediaInputHideInputStatus : public ClusterCommand {
public:
    MediaInputHideInputStatus()
        : ClusterCommand("hide-input-status")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRMediaInputClusterHideInputStatusParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster hideInputStatusWithParams:params
                                    completion:^(NSError * _Nullable error) {
                                        responsesNeeded--;
                                        if (error != nil) {
                                            mError = error;
                                            LogNSError("Error", error);
                                        }
                                        if (responsesNeeded == 0) {
                                            SetCommandExitStatus(mError);
                                        }
                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command RenameInput
 */
class MediaInputRenameInput : public ClusterCommand {
public:
    MediaInputRenameInput()
        : ClusterCommand("rename-input")
    {
        AddArgument("Index", 0, UINT8_MAX, &mRequest.index);
        AddArgument("Name", &mRequest.name);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRMediaInputClusterRenameInputParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.index = [NSNumber numberWithUnsignedChar:mRequest.index];
        params.name = [[NSString alloc] initWithBytes:mRequest.name.data()
                                               length:mRequest.name.size()
                                             encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster renameInputWithParams:params
                                completion:^(NSError * _Nullable error) {
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::MediaInput::Commands::RenameInput::Type mRequest;
};

/*
 * Attribute InputList
 */
class ReadMediaInputInputList : public ReadAttribute {
public:
    ReadMediaInputInputList()
        : ReadAttribute("input-list")
    {
    }

    ~ReadMediaInputInputList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeInputListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.InputList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput InputList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputInputList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputInputList()
        : SubscribeAttribute("input-list")
    {
    }

    ~SubscribeAttributeMediaInputInputList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInputListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.InputList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentInput
 */
class ReadMediaInputCurrentInput : public ReadAttribute {
public:
    ReadMediaInputCurrentInput()
        : ReadAttribute("current-input")
    {
    }

    ~ReadMediaInputCurrentInput() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeCurrentInputWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.CurrentInput response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput CurrentInput read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputCurrentInput : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputCurrentInput()
        : SubscribeAttribute("current-input")
    {
    }

    ~SubscribeAttributeMediaInputCurrentInput() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentInputWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.CurrentInput response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadMediaInputGeneratedCommandList : public ReadAttribute {
public:
    ReadMediaInputGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadMediaInputGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeMediaInputGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadMediaInputAcceptedCommandList : public ReadAttribute {
public:
    ReadMediaInputAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadMediaInputAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeMediaInputAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadMediaInputAttributeList : public ReadAttribute {
public:
    ReadMediaInputAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadMediaInputAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeMediaInputAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadMediaInputFeatureMap : public ReadAttribute {
public:
    ReadMediaInputFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadMediaInputFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeMediaInputFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadMediaInputClusterRevision : public ReadAttribute {
public:
    ReadMediaInputClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadMediaInputClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeMediaInputClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster LowPower                                                    | 0x0508 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * Sleep                                                             |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command Sleep
 */
class LowPowerSleep : public ClusterCommand {
public:
    LowPowerSleep()
        : ClusterCommand("sleep")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRLowPowerClusterSleepParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster sleepWithParams:params
                          completion:^(NSError * _Nullable error) {
                              responsesNeeded--;
                              if (error != nil) {
                                  mError = error;
                                  LogNSError("Error", error);
                              }
                              if (responsesNeeded == 0) {
                                  SetCommandExitStatus(mError);
                              }
                          }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute GeneratedCommandList
 */
class ReadLowPowerGeneratedCommandList : public ReadAttribute {
public:
    ReadLowPowerGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadLowPowerGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LowPower.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("LowPower GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLowPowerGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeLowPowerGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeLowPowerGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LowPower.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadLowPowerAcceptedCommandList : public ReadAttribute {
public:
    ReadLowPowerAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadLowPowerAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LowPower.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("LowPower AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLowPowerAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeLowPowerAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeLowPowerAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LowPower.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadLowPowerAttributeList : public ReadAttribute {
public:
    ReadLowPowerAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadLowPowerAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LowPower.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("LowPower AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLowPowerAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeLowPowerAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeLowPowerAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LowPower.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadLowPowerFeatureMap : public ReadAttribute {
public:
    ReadLowPowerFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadLowPowerFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LowPower.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("LowPower FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLowPowerFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeLowPowerFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeLowPowerFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LowPower.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadLowPowerClusterRevision : public ReadAttribute {
public:
    ReadLowPowerClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadLowPowerClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LowPower.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("LowPower ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLowPowerClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeLowPowerClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeLowPowerClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LowPower.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster KeypadInput                                                 | 0x0509 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * SendKey                                                           |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command SendKey
 */
class KeypadInputSendKey : public ClusterCommand {
public:
    KeypadInputSendKey()
        : ClusterCommand("send-key")
    {
        AddArgument("KeyCode", 0, UINT8_MAX, &mRequest.keyCode);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRKeypadInputClusterSendKeyParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.keyCode = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.keyCode)];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster sendKeyWithParams:params
                            completion:^(MTRKeypadInputClusterSendKeyResponseParams * _Nullable values, NSError * _Nullable error) {
                                NSLog(@"Values: %@", values);
                                responsesNeeded--;
                                if (error != nil) {
                                    mError = error;
                                    LogNSError("Error", error);
                                }
                                if (responsesNeeded == 0) {
                                    SetCommandExitStatus(mError);
                                }
                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::KeypadInput::Commands::SendKey::Type mRequest;
};

/*
 * Attribute GeneratedCommandList
 */
class ReadKeypadInputGeneratedCommandList : public ReadAttribute {
public:
    ReadKeypadInputGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadKeypadInputGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"KeypadInput.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("KeypadInput GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeKeypadInputGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeKeypadInputGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeKeypadInputGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"KeypadInput.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadKeypadInputAcceptedCommandList : public ReadAttribute {
public:
    ReadKeypadInputAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadKeypadInputAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"KeypadInput.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("KeypadInput AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeKeypadInputAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeKeypadInputAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeKeypadInputAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"KeypadInput.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadKeypadInputAttributeList : public ReadAttribute {
public:
    ReadKeypadInputAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadKeypadInputAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"KeypadInput.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("KeypadInput AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeKeypadInputAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeKeypadInputAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeKeypadInputAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"KeypadInput.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadKeypadInputFeatureMap : public ReadAttribute {
public:
    ReadKeypadInputFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadKeypadInputFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"KeypadInput.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("KeypadInput FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeKeypadInputFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeKeypadInputFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeKeypadInputFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"KeypadInput.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadKeypadInputClusterRevision : public ReadAttribute {
public:
    ReadKeypadInputClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadKeypadInputClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"KeypadInput.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("KeypadInput ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeKeypadInputClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeKeypadInputClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeKeypadInputClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"KeypadInput.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ContentLauncher                                             | 0x050A |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * LaunchContent                                                     |   0x00 |
| * LaunchURL                                                         |   0x01 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * AcceptHeader                                                      | 0x0000 |
| * SupportedStreamingProtocols                                       | 0x0001 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command LaunchContent
 */
class ContentLauncherLaunchContent : public ClusterCommand {
public:
    ContentLauncherLaunchContent()
        : ClusterCommand("launch-content")
        , mComplex_Search(&mRequest.search)
    {
        AddArgument("Search", &mComplex_Search);
        AddArgument("AutoPlay", 0, 1, &mRequest.autoPlay);
        AddArgument("Data", &mRequest.data);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRContentLauncherClusterLaunchContentParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.search = [MTRContentLauncherClusterContentSearchStruct new];
        { // Scope for our temporary variables
            auto * array_1 = [NSMutableArray new];
            for (auto & entry_1 : mRequest.search.parameterList) {
                MTRContentLauncherClusterParameterStruct * newElement_1;
                newElement_1 = [MTRContentLauncherClusterParameterStruct new];
                newElement_1.type = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1.type)];
                newElement_1.value = [[NSString alloc] initWithBytes:entry_1.value.data()
                                                              length:entry_1.value.size()
                                                            encoding:NSUTF8StringEncoding];
                if (entry_1.externalIDList.HasValue()) {
                    { // Scope for our temporary variables
                        auto * array_4 = [NSMutableArray new];
                        for (auto & entry_4 : entry_1.externalIDList.Value()) {
                            MTRContentLauncherClusterAdditionalInfoStruct * newElement_4;
                            newElement_4 = [MTRContentLauncherClusterAdditionalInfoStruct new];
                            newElement_4.name = [[NSString alloc] initWithBytes:entry_4.name.data()
                                                                         length:entry_4.name.size()
                                                                       encoding:NSUTF8StringEncoding];
                            newElement_4.value = [[NSString alloc] initWithBytes:entry_4.value.data()
                                                                          length:entry_4.value.size()
                                                                        encoding:NSUTF8StringEncoding];
                            [array_4 addObject:newElement_4];
                        }
                        newElement_1.externalIDList = array_4;
                    }
                } else {
                    newElement_1.externalIDList = nil;
                }
                [array_1 addObject:newElement_1];
            }
            params.search.parameterList = array_1;
        }
        params.autoPlay = [NSNumber numberWithBool:mRequest.autoPlay];
        if (mRequest.data.HasValue()) {
            params.data = [[NSString alloc] initWithBytes:mRequest.data.Value().data()
                                                   length:mRequest.data.Value().size()
                                                 encoding:NSUTF8StringEncoding];
        } else {
            params.data = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster launchContentWithParams:params
                                  completion:^(MTRContentLauncherClusterLauncherResponseParams * _Nullable values,
                                      NSError * _Nullable error) {
                                      NSLog(@"Values: %@", values);
                                      responsesNeeded--;
                                      if (error != nil) {
                                          mError = error;
                                          LogNSError("Error", error);
                                      }
                                      if (responsesNeeded == 0) {
                                          SetCommandExitStatus(mError);
                                      }
                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ContentLauncher::Commands::LaunchContent::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::ContentLauncher::Structs::ContentSearchStruct::Type> mComplex_Search;
};

/*
 * Command LaunchURL
 */
class ContentLauncherLaunchURL : public ClusterCommand {
public:
    ContentLauncherLaunchURL()
        : ClusterCommand("launch-url")
        , mComplex_BrandingInformation(&mRequest.brandingInformation)
    {
        AddArgument("ContentURL", &mRequest.contentURL);
        AddArgument("DisplayString", &mRequest.displayString);
        AddArgument("BrandingInformation", &mComplex_BrandingInformation);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRContentLauncherClusterLaunchURLParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.contentURL = [[NSString alloc] initWithBytes:mRequest.contentURL.data()
                                                     length:mRequest.contentURL.size()
                                                   encoding:NSUTF8StringEncoding];
        if (mRequest.displayString.HasValue()) {
            params.displayString = [[NSString alloc] initWithBytes:mRequest.displayString.Value().data()
                                                            length:mRequest.displayString.Value().size()
                                                          encoding:NSUTF8StringEncoding];
        } else {
            params.displayString = nil;
        }
        if (mRequest.brandingInformation.HasValue()) {
            params.brandingInformation = [MTRContentLauncherClusterBrandingInformationStruct new];
            params.brandingInformation.providerName =
                [[NSString alloc] initWithBytes:mRequest.brandingInformation.Value().providerName.data()
                                         length:mRequest.brandingInformation.Value().providerName.size()
                                       encoding:NSUTF8StringEncoding];
            if (mRequest.brandingInformation.Value().background.HasValue()) {
                params.brandingInformation.background = [MTRContentLauncherClusterStyleInformationStruct new];
                if (mRequest.brandingInformation.Value().background.Value().imageURL.HasValue()) {
                    params.brandingInformation.background.imageURL = [[NSString alloc]
                        initWithBytes:mRequest.brandingInformation.Value().background.Value().imageURL.Value().data()
                               length:mRequest.brandingInformation.Value().background.Value().imageURL.Value().size()
                             encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.background.imageURL = nil;
                }
                if (mRequest.brandingInformation.Value().background.Value().color.HasValue()) {
                    params.brandingInformation.background.color =
                        [[NSString alloc] initWithBytes:mRequest.brandingInformation.Value().background.Value().color.Value().data()
                                                 length:mRequest.brandingInformation.Value().background.Value().color.Value().size()
                                               encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.background.color = nil;
                }
                if (mRequest.brandingInformation.Value().background.Value().size.HasValue()) {
                    params.brandingInformation.background.size = [MTRContentLauncherClusterDimensionStruct new];
                    params.brandingInformation.background.size.width =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().background.Value().size.Value().width];
                    params.brandingInformation.background.size.height =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().background.Value().size.Value().height];
                    params.brandingInformation.background.size.metric = [NSNumber
                        numberWithUnsignedChar:chip::to_underlying(
                                                   mRequest.brandingInformation.Value().background.Value().size.Value().metric)];
                } else {
                    params.brandingInformation.background.size = nil;
                }
            } else {
                params.brandingInformation.background = nil;
            }
            if (mRequest.brandingInformation.Value().logo.HasValue()) {
                params.brandingInformation.logo = [MTRContentLauncherClusterStyleInformationStruct new];
                if (mRequest.brandingInformation.Value().logo.Value().imageURL.HasValue()) {
                    params.brandingInformation.logo.imageURL =
                        [[NSString alloc] initWithBytes:mRequest.brandingInformation.Value().logo.Value().imageURL.Value().data()
                                                 length:mRequest.brandingInformation.Value().logo.Value().imageURL.Value().size()
                                               encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.logo.imageURL = nil;
                }
                if (mRequest.brandingInformation.Value().logo.Value().color.HasValue()) {
                    params.brandingInformation.logo.color =
                        [[NSString alloc] initWithBytes:mRequest.brandingInformation.Value().logo.Value().color.Value().data()
                                                 length:mRequest.brandingInformation.Value().logo.Value().color.Value().size()
                                               encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.logo.color = nil;
                }
                if (mRequest.brandingInformation.Value().logo.Value().size.HasValue()) {
                    params.brandingInformation.logo.size = [MTRContentLauncherClusterDimensionStruct new];
                    params.brandingInformation.logo.size.width =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().logo.Value().size.Value().width];
                    params.brandingInformation.logo.size.height =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().logo.Value().size.Value().height];
                    params.brandingInformation.logo.size.metric = [NSNumber
                        numberWithUnsignedChar:chip::to_underlying(
                                                   mRequest.brandingInformation.Value().logo.Value().size.Value().metric)];
                } else {
                    params.brandingInformation.logo.size = nil;
                }
            } else {
                params.brandingInformation.logo = nil;
            }
            if (mRequest.brandingInformation.Value().progressBar.HasValue()) {
                params.brandingInformation.progressBar = [MTRContentLauncherClusterStyleInformationStruct new];
                if (mRequest.brandingInformation.Value().progressBar.Value().imageURL.HasValue()) {
                    params.brandingInformation.progressBar.imageURL = [[NSString alloc]
                        initWithBytes:mRequest.brandingInformation.Value().progressBar.Value().imageURL.Value().data()
                               length:mRequest.brandingInformation.Value().progressBar.Value().imageURL.Value().size()
                             encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.progressBar.imageURL = nil;
                }
                if (mRequest.brandingInformation.Value().progressBar.Value().color.HasValue()) {
                    params.brandingInformation.progressBar.color = [[NSString alloc]
                        initWithBytes:mRequest.brandingInformation.Value().progressBar.Value().color.Value().data()
                               length:mRequest.brandingInformation.Value().progressBar.Value().color.Value().size()
                             encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.progressBar.color = nil;
                }
                if (mRequest.brandingInformation.Value().progressBar.Value().size.HasValue()) {
                    params.brandingInformation.progressBar.size = [MTRContentLauncherClusterDimensionStruct new];
                    params.brandingInformation.progressBar.size.width =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().progressBar.Value().size.Value().width];
                    params.brandingInformation.progressBar.size.height =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().progressBar.Value().size.Value().height];
                    params.brandingInformation.progressBar.size.metric = [NSNumber
                        numberWithUnsignedChar:chip::to_underlying(
                                                   mRequest.brandingInformation.Value().progressBar.Value().size.Value().metric)];
                } else {
                    params.brandingInformation.progressBar.size = nil;
                }
            } else {
                params.brandingInformation.progressBar = nil;
            }
            if (mRequest.brandingInformation.Value().splash.HasValue()) {
                params.brandingInformation.splash = [MTRContentLauncherClusterStyleInformationStruct new];
                if (mRequest.brandingInformation.Value().splash.Value().imageURL.HasValue()) {
                    params.brandingInformation.splash.imageURL =
                        [[NSString alloc] initWithBytes:mRequest.brandingInformation.Value().splash.Value().imageURL.Value().data()
                                                 length:mRequest.brandingInformation.Value().splash.Value().imageURL.Value().size()
                                               encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.splash.imageURL = nil;
                }
                if (mRequest.brandingInformation.Value().splash.Value().color.HasValue()) {
                    params.brandingInformation.splash.color =
                        [[NSString alloc] initWithBytes:mRequest.brandingInformation.Value().splash.Value().color.Value().data()
                                                 length:mRequest.brandingInformation.Value().splash.Value().color.Value().size()
                                               encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.splash.color = nil;
                }
                if (mRequest.brandingInformation.Value().splash.Value().size.HasValue()) {
                    params.brandingInformation.splash.size = [MTRContentLauncherClusterDimensionStruct new];
                    params.brandingInformation.splash.size.width =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().splash.Value().size.Value().width];
                    params.brandingInformation.splash.size.height =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().splash.Value().size.Value().height];
                    params.brandingInformation.splash.size.metric = [NSNumber
                        numberWithUnsignedChar:chip::to_underlying(
                                                   mRequest.brandingInformation.Value().splash.Value().size.Value().metric)];
                } else {
                    params.brandingInformation.splash.size = nil;
                }
            } else {
                params.brandingInformation.splash = nil;
            }
            if (mRequest.brandingInformation.Value().waterMark.HasValue()) {
                params.brandingInformation.waterMark = [MTRContentLauncherClusterStyleInformationStruct new];
                if (mRequest.brandingInformation.Value().waterMark.Value().imageURL.HasValue()) {
                    params.brandingInformation.waterMark.imageURL = [[NSString alloc]
                        initWithBytes:mRequest.brandingInformation.Value().waterMark.Value().imageURL.Value().data()
                               length:mRequest.brandingInformation.Value().waterMark.Value().imageURL.Value().size()
                             encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.waterMark.imageURL = nil;
                }
                if (mRequest.brandingInformation.Value().waterMark.Value().color.HasValue()) {
                    params.brandingInformation.waterMark.color =
                        [[NSString alloc] initWithBytes:mRequest.brandingInformation.Value().waterMark.Value().color.Value().data()
                                                 length:mRequest.brandingInformation.Value().waterMark.Value().color.Value().size()
                                               encoding:NSUTF8StringEncoding];
                } else {
                    params.brandingInformation.waterMark.color = nil;
                }
                if (mRequest.brandingInformation.Value().waterMark.Value().size.HasValue()) {
                    params.brandingInformation.waterMark.size = [MTRContentLauncherClusterDimensionStruct new];
                    params.brandingInformation.waterMark.size.width =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().waterMark.Value().size.Value().width];
                    params.brandingInformation.waterMark.size.height =
                        [NSNumber numberWithDouble:mRequest.brandingInformation.Value().waterMark.Value().size.Value().height];
                    params.brandingInformation.waterMark.size.metric = [NSNumber
                        numberWithUnsignedChar:chip::to_underlying(
                                                   mRequest.brandingInformation.Value().waterMark.Value().size.Value().metric)];
                } else {
                    params.brandingInformation.waterMark.size = nil;
                }
            } else {
                params.brandingInformation.waterMark = nil;
            }
        } else {
            params.brandingInformation = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster launchURLWithParams:params
                              completion:^(
                                  MTRContentLauncherClusterLauncherResponseParams * _Nullable values, NSError * _Nullable error) {
                                  NSLog(@"Values: %@", values);
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ContentLauncher::Commands::LaunchURL::Type mRequest;
    TypedComplexArgument<chip::Optional<chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::Type>>
        mComplex_BrandingInformation;
};

/*
 * Attribute AcceptHeader
 */
class ReadContentLauncherAcceptHeader : public ReadAttribute {
public:
    ReadContentLauncherAcceptHeader()
        : ReadAttribute("accept-header")
    {
    }

    ~ReadContentLauncherAcceptHeader() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeAcceptHeaderWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.AcceptHeader response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher AcceptHeader read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeContentLauncherAcceptHeader : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherAcceptHeader()
        : SubscribeAttribute("accept-header")
    {
    }

    ~SubscribeAttributeContentLauncherAcceptHeader() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptHeaderWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.AcceptHeader response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SupportedStreamingProtocols
 */
class ReadContentLauncherSupportedStreamingProtocols : public ReadAttribute {
public:
    ReadContentLauncherSupportedStreamingProtocols()
        : ReadAttribute("supported-streaming-protocols")
    {
    }

    ~ReadContentLauncherSupportedStreamingProtocols() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeSupportedStreamingProtocolsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.SupportedStreamingProtocols response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher SupportedStreamingProtocols read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteContentLauncherSupportedStreamingProtocols : public WriteAttribute {
public:
    WriteContentLauncherSupportedStreamingProtocols()
        : WriteAttribute("supported-streaming-protocols")
    {
        AddArgument("attr-name", "supported-streaming-protocols");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteContentLauncherSupportedStreamingProtocols() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) WriteAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster
            writeAttributeSupportedStreamingProtocolsWithValue:value
                                                        params:params
                                                    completion:^(NSError * _Nullable error) {
                                                        if (error != nil) {
                                                            LogNSError(
                                                                "ContentLauncher SupportedStreamingProtocols write Error", error);
                                                        }
                                                        SetCommandExitStatus(error);
                                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeContentLauncherSupportedStreamingProtocols : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherSupportedStreamingProtocols()
        : SubscribeAttribute("supported-streaming-protocols")
    {
    }

    ~SubscribeAttributeContentLauncherSupportedStreamingProtocols() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeSupportedStreamingProtocolsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.SupportedStreamingProtocols response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadContentLauncherGeneratedCommandList : public ReadAttribute {
public:
    ReadContentLauncherGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadContentLauncherGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeContentLauncherGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeContentLauncherGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadContentLauncherAcceptedCommandList : public ReadAttribute {
public:
    ReadContentLauncherAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadContentLauncherAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeContentLauncherAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeContentLauncherAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadContentLauncherAttributeList : public ReadAttribute {
public:
    ReadContentLauncherAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadContentLauncherAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeContentLauncherAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeContentLauncherAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadContentLauncherFeatureMap : public ReadAttribute {
public:
    ReadContentLauncherFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadContentLauncherFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeContentLauncherFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeContentLauncherFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadContentLauncherClusterRevision : public ReadAttribute {
public:
    ReadContentLauncherClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadContentLauncherClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeContentLauncherClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeContentLauncherClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device
                                                                           endpointID:@(endpointId)
                                                                                queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster AudioOutput                                                 | 0x050B |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * SelectOutput                                                      |   0x00 |
| * RenameOutput                                                      |   0x01 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * OutputList                                                        | 0x0000 |
| * CurrentOutput                                                     | 0x0001 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command SelectOutput
 */
class AudioOutputSelectOutput : public ClusterCommand {
public:
    AudioOutputSelectOutput()
        : ClusterCommand("select-output")
    {
        AddArgument("Index", 0, UINT8_MAX, &mRequest.index);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRAudioOutputClusterSelectOutputParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.index = [NSNumber numberWithUnsignedChar:mRequest.index];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster selectOutputWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::AudioOutput::Commands::SelectOutput::Type mRequest;
};

/*
 * Command RenameOutput
 */
class AudioOutputRenameOutput : public ClusterCommand {
public:
    AudioOutputRenameOutput()
        : ClusterCommand("rename-output")
    {
        AddArgument("Index", 0, UINT8_MAX, &mRequest.index);
        AddArgument("Name", &mRequest.name);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRAudioOutputClusterRenameOutputParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.index = [NSNumber numberWithUnsignedChar:mRequest.index];
        params.name = [[NSString alloc] initWithBytes:mRequest.name.data()
                                               length:mRequest.name.size()
                                             encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster renameOutputWithParams:params
                                 completion:^(NSError * _Nullable error) {
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::AudioOutput::Commands::RenameOutput::Type mRequest;
};

/*
 * Attribute OutputList
 */
class ReadAudioOutputOutputList : public ReadAttribute {
public:
    ReadAudioOutputOutputList()
        : ReadAttribute("output-list")
    {
    }

    ~ReadAudioOutputOutputList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeOutputListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.OutputList response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput OutputList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputOutputList : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputOutputList()
        : SubscribeAttribute("output-list")
    {
    }

    ~SubscribeAttributeAudioOutputOutputList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOutputListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.OutputList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentOutput
 */
class ReadAudioOutputCurrentOutput : public ReadAttribute {
public:
    ReadAudioOutputCurrentOutput()
        : ReadAttribute("current-output")
    {
    }

    ~ReadAudioOutputCurrentOutput() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeCurrentOutputWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.CurrentOutput response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput CurrentOutput read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputCurrentOutput : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputCurrentOutput()
        : SubscribeAttribute("current-output")
    {
    }

    ~SubscribeAttributeAudioOutputCurrentOutput() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentOutputWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.CurrentOutput response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadAudioOutputGeneratedCommandList : public ReadAttribute {
public:
    ReadAudioOutputGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadAudioOutputGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeAudioOutputGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadAudioOutputAcceptedCommandList : public ReadAttribute {
public:
    ReadAudioOutputAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadAudioOutputAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeAudioOutputAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadAudioOutputAttributeList : public ReadAttribute {
public:
    ReadAudioOutputAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadAudioOutputAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeAudioOutputAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadAudioOutputFeatureMap : public ReadAttribute {
public:
    ReadAudioOutputFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadAudioOutputFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeAudioOutputFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadAudioOutputClusterRevision : public ReadAttribute {
public:
    ReadAudioOutputClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadAudioOutputClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeAudioOutputClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ApplicationLauncher                                         | 0x050C |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * LaunchApp                                                         |   0x00 |
| * StopApp                                                           |   0x01 |
| * HideApp                                                           |   0x02 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * CatalogList                                                       | 0x0000 |
| * CurrentApp                                                        | 0x0001 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command LaunchApp
 */
class ApplicationLauncherLaunchApp : public ClusterCommand {
public:
    ApplicationLauncherLaunchApp()
        : ClusterCommand("launch-app")
        , mComplex_Application(&mRequest.application)
    {
        AddArgument("Application", &mComplex_Application);
        AddArgument("Data", &mRequest.data);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRApplicationLauncherClusterLaunchAppParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.application.HasValue()) {
            params.application = [MTRApplicationLauncherClusterApplicationStruct new];
            params.application.catalogVendorID = [NSNumber numberWithUnsignedShort:mRequest.application.Value().catalogVendorID];
            params.application.applicationID = [[NSString alloc] initWithBytes:mRequest.application.Value().applicationID.data()
                                                                        length:mRequest.application.Value().applicationID.size()
                                                                      encoding:NSUTF8StringEncoding];
        } else {
            params.application = nil;
        }
        if (mRequest.data.HasValue()) {
            params.data = [NSData dataWithBytes:mRequest.data.Value().data() length:mRequest.data.Value().size()];
        } else {
            params.data = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster launchAppWithParams:params
                              completion:^(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable values,
                                  NSError * _Nullable error) {
                                  NSLog(@"Values: %@", values);
                                  responsesNeeded--;
                                  if (error != nil) {
                                      mError = error;
                                      LogNSError("Error", error);
                                  }
                                  if (responsesNeeded == 0) {
                                      SetCommandExitStatus(mError);
                                  }
                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ApplicationLauncher::Commands::LaunchApp::Type mRequest;
    TypedComplexArgument<chip::Optional<chip::app::Clusters::ApplicationLauncher::Structs::ApplicationStruct::Type>>
        mComplex_Application;
};

/*
 * Command StopApp
 */
class ApplicationLauncherStopApp : public ClusterCommand {
public:
    ApplicationLauncherStopApp()
        : ClusterCommand("stop-app")
        , mComplex_Application(&mRequest.application)
    {
        AddArgument("Application", &mComplex_Application);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRApplicationLauncherClusterStopAppParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.application.HasValue()) {
            params.application = [MTRApplicationLauncherClusterApplicationStruct new];
            params.application.catalogVendorID = [NSNumber numberWithUnsignedShort:mRequest.application.Value().catalogVendorID];
            params.application.applicationID = [[NSString alloc] initWithBytes:mRequest.application.Value().applicationID.data()
                                                                        length:mRequest.application.Value().applicationID.size()
                                                                      encoding:NSUTF8StringEncoding];
        } else {
            params.application = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster stopAppWithParams:params
                            completion:^(
                                MTRApplicationLauncherClusterLauncherResponseParams * _Nullable values, NSError * _Nullable error) {
                                NSLog(@"Values: %@", values);
                                responsesNeeded--;
                                if (error != nil) {
                                    mError = error;
                                    LogNSError("Error", error);
                                }
                                if (responsesNeeded == 0) {
                                    SetCommandExitStatus(mError);
                                }
                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ApplicationLauncher::Commands::StopApp::Type mRequest;
    TypedComplexArgument<chip::Optional<chip::app::Clusters::ApplicationLauncher::Structs::ApplicationStruct::Type>>
        mComplex_Application;
};

/*
 * Command HideApp
 */
class ApplicationLauncherHideApp : public ClusterCommand {
public:
    ApplicationLauncherHideApp()
        : ClusterCommand("hide-app")
        , mComplex_Application(&mRequest.application)
    {
        AddArgument("Application", &mComplex_Application);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRApplicationLauncherClusterHideAppParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.application.HasValue()) {
            params.application = [MTRApplicationLauncherClusterApplicationStruct new];
            params.application.catalogVendorID = [NSNumber numberWithUnsignedShort:mRequest.application.Value().catalogVendorID];
            params.application.applicationID = [[NSString alloc] initWithBytes:mRequest.application.Value().applicationID.data()
                                                                        length:mRequest.application.Value().applicationID.size()
                                                                      encoding:NSUTF8StringEncoding];
        } else {
            params.application = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster hideAppWithParams:params
                            completion:^(
                                MTRApplicationLauncherClusterLauncherResponseParams * _Nullable values, NSError * _Nullable error) {
                                NSLog(@"Values: %@", values);
                                responsesNeeded--;
                                if (error != nil) {
                                    mError = error;
                                    LogNSError("Error", error);
                                }
                                if (responsesNeeded == 0) {
                                    SetCommandExitStatus(mError);
                                }
                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ApplicationLauncher::Commands::HideApp::Type mRequest;
    TypedComplexArgument<chip::Optional<chip::app::Clusters::ApplicationLauncher::Structs::ApplicationStruct::Type>>
        mComplex_Application;
};

/*
 * Attribute CatalogList
 */
class ReadApplicationLauncherCatalogList : public ReadAttribute {
public:
    ReadApplicationLauncherCatalogList()
        : ReadAttribute("catalog-list")
    {
    }

    ~ReadApplicationLauncherCatalogList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeCatalogListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.CatalogList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher CatalogList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationLauncherCatalogList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherCatalogList()
        : SubscribeAttribute("catalog-list")
    {
    }

    ~SubscribeAttributeApplicationLauncherCatalogList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCatalogListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.CatalogList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentApp
 */
class ReadApplicationLauncherCurrentApp : public ReadAttribute {
public:
    ReadApplicationLauncherCurrentApp()
        : ReadAttribute("current-app")
    {
    }

    ~ReadApplicationLauncherCurrentApp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeCurrentAppWithCompletion:^(
            MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.CurrentApp response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher CurrentApp read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteApplicationLauncherCurrentApp : public WriteAttribute {
public:
    WriteApplicationLauncherCurrentApp()
        : WriteAttribute("current-app")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "current-app");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteApplicationLauncherCurrentApp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) WriteAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value;
        if (mValue.IsNull()) {
            value = nil;
        } else {
            value = [MTRApplicationLauncherClusterApplicationEPStruct new];
            value.application = [MTRApplicationLauncherClusterApplicationStruct new];
            value.application.catalogVendorID = [NSNumber numberWithUnsignedShort:mValue.Value().application.catalogVendorID];
            value.application.applicationID = [[NSString alloc] initWithBytes:mValue.Value().application.applicationID.data()
                                                                       length:mValue.Value().application.applicationID.size()
                                                                     encoding:NSUTF8StringEncoding];
            if (mValue.Value().endpoint.HasValue()) {
                value.endpoint = [NSNumber numberWithUnsignedShort:mValue.Value().endpoint.Value()];
            } else {
                value.endpoint = nil;
            }
        }

        [cluster writeAttributeCurrentAppWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("ApplicationLauncher CurrentApp write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::Nullable<chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEPStruct::Type> mValue;
    TypedComplexArgument<
        chip::app::DataModel::Nullable<chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEPStruct::Type>>
        mComplex;
};

class SubscribeAttributeApplicationLauncherCurrentApp : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherCurrentApp()
        : SubscribeAttribute("current-app")
    {
    }

    ~SubscribeAttributeApplicationLauncherCurrentApp() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentAppWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.CurrentApp response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadApplicationLauncherGeneratedCommandList : public ReadAttribute {
public:
    ReadApplicationLauncherGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadApplicationLauncherGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationLauncherGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeApplicationLauncherGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadApplicationLauncherAcceptedCommandList : public ReadAttribute {
public:
    ReadApplicationLauncherAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadApplicationLauncherAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationLauncherAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeApplicationLauncherAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadApplicationLauncherAttributeList : public ReadAttribute {
public:
    ReadApplicationLauncherAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadApplicationLauncherAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationLauncherAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeApplicationLauncherAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadApplicationLauncherFeatureMap : public ReadAttribute {
public:
    ReadApplicationLauncherFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadApplicationLauncherFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationLauncherFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeApplicationLauncherFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadApplicationLauncherClusterRevision : public ReadAttribute {
public:
    ReadApplicationLauncherClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadApplicationLauncherClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationLauncherClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeApplicationLauncherClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device
                                                                               endpointID:@(endpointId)
                                                                                    queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ApplicationBasic                                            | 0x050D |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * VendorName                                                        | 0x0000 |
| * VendorID                                                          | 0x0001 |
| * ApplicationName                                                   | 0x0002 |
| * ProductID                                                         | 0x0003 |
| * Application                                                       | 0x0004 |
| * Status                                                            | 0x0005 |
| * ApplicationVersion                                                | 0x0006 |
| * AllowedVendorList                                                 | 0x0007 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute VendorName
 */
class ReadApplicationBasicVendorName : public ReadAttribute {
public:
    ReadApplicationBasicVendorName()
        : ReadAttribute("vendor-name")
    {
    }

    ~ReadApplicationBasicVendorName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeVendorNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.VendorName response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic VendorName read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicVendorName : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicVendorName()
        : SubscribeAttribute("vendor-name")
    {
    }

    ~SubscribeAttributeApplicationBasicVendorName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVendorNameWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.VendorName response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute VendorID
 */
class ReadApplicationBasicVendorID : public ReadAttribute {
public:
    ReadApplicationBasicVendorID()
        : ReadAttribute("vendor-id")
    {
    }

    ~ReadApplicationBasicVendorID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeVendorIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.VendorID response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic VendorID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicVendorID : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicVendorID()
        : SubscribeAttribute("vendor-id")
    {
    }

    ~SubscribeAttributeApplicationBasicVendorID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVendorIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.VendorID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ApplicationName
 */
class ReadApplicationBasicApplicationName : public ReadAttribute {
public:
    ReadApplicationBasicApplicationName()
        : ReadAttribute("application-name")
    {
    }

    ~ReadApplicationBasicApplicationName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeApplicationNameWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.ApplicationName response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic ApplicationName read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicApplicationName : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicApplicationName()
        : SubscribeAttribute("application-name")
    {
    }

    ~SubscribeAttributeApplicationBasicApplicationName() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeApplicationNameWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.ApplicationName response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ProductID
 */
class ReadApplicationBasicProductID : public ReadAttribute {
public:
    ReadApplicationBasicProductID()
        : ReadAttribute("product-id")
    {
    }

    ~ReadApplicationBasicProductID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeProductIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.ProductID response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic ProductID read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicProductID : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicProductID()
        : SubscribeAttribute("product-id")
    {
    }

    ~SubscribeAttributeApplicationBasicProductID() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeProductIDWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.ProductID response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Application
 */
class ReadApplicationBasicApplication : public ReadAttribute {
public:
    ReadApplicationBasicApplication()
        : ReadAttribute("application")
    {
    }

    ~ReadApplicationBasicApplication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeApplicationWithCompletion:^(
            MTRApplicationBasicClusterApplicationStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.Application response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic Application read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicApplication : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicApplication()
        : SubscribeAttribute("application")
    {
    }

    ~SubscribeAttributeApplicationBasicApplication() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeApplicationWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRApplicationBasicClusterApplicationStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.Application response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Status
 */
class ReadApplicationBasicStatus : public ReadAttribute {
public:
    ReadApplicationBasicStatus()
        : ReadAttribute("status")
    {
    }

    ~ReadApplicationBasicStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeStatusWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.Status response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic Status read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicStatus : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicStatus()
        : SubscribeAttribute("status")
    {
    }

    ~SubscribeAttributeApplicationBasicStatus() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStatusWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.Status response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ApplicationVersion
 */
class ReadApplicationBasicApplicationVersion : public ReadAttribute {
public:
    ReadApplicationBasicApplicationVersion()
        : ReadAttribute("application-version")
    {
    }

    ~ReadApplicationBasicApplicationVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeApplicationVersionWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.ApplicationVersion response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic ApplicationVersion read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicApplicationVersion : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicApplicationVersion()
        : SubscribeAttribute("application-version")
    {
    }

    ~SubscribeAttributeApplicationBasicApplicationVersion() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeApplicationVersionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.ApplicationVersion response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AllowedVendorList
 */
class ReadApplicationBasicAllowedVendorList : public ReadAttribute {
public:
    ReadApplicationBasicAllowedVendorList()
        : ReadAttribute("allowed-vendor-list")
    {
    }

    ~ReadApplicationBasicAllowedVendorList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAllowedVendorListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.AllowedVendorList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic AllowedVendorList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicAllowedVendorList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicAllowedVendorList()
        : SubscribeAttribute("allowed-vendor-list")
    {
    }

    ~SubscribeAttributeApplicationBasicAllowedVendorList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAllowedVendorListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.AllowedVendorList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadApplicationBasicGeneratedCommandList : public ReadAttribute {
public:
    ReadApplicationBasicGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadApplicationBasicGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeApplicationBasicGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadApplicationBasicAcceptedCommandList : public ReadAttribute {
public:
    ReadApplicationBasicAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadApplicationBasicAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeApplicationBasicAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadApplicationBasicAttributeList : public ReadAttribute {
public:
    ReadApplicationBasicAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadApplicationBasicAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeApplicationBasicAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadApplicationBasicFeatureMap : public ReadAttribute {
public:
    ReadApplicationBasicFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadApplicationBasicFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeApplicationBasicFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadApplicationBasicClusterRevision : public ReadAttribute {
public:
    ReadApplicationBasicClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadApplicationBasicClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeApplicationBasicClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device
                                                                            endpointID:@(endpointId)
                                                                                 queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster AccountLogin                                                | 0x050E |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * GetSetupPIN                                                       |   0x00 |
| * Login                                                             |   0x02 |
| * Logout                                                            |   0x03 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command GetSetupPIN
 */
class AccountLoginGetSetupPIN : public ClusterCommand {
public:
    AccountLoginGetSetupPIN()
        : ClusterCommand("get-setup-pin")
    {
        AddArgument("TempAccountIdentifier", &mRequest.tempAccountIdentifier);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRAccountLoginClusterGetSetupPINParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.tempAccountIdentifier = [[NSString alloc] initWithBytes:mRequest.tempAccountIdentifier.data()
                                                                length:mRequest.tempAccountIdentifier.size()
                                                              encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getSetupPINWithParams:params
                                completion:^(
                                    MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable values, NSError * _Nullable error) {
                                    NSLog(@"Values: %@", values);
                                    responsesNeeded--;
                                    if (error != nil) {
                                        mError = error;
                                        LogNSError("Error", error);
                                    }
                                    if (responsesNeeded == 0) {
                                        SetCommandExitStatus(mError);
                                    }
                                }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::AccountLogin::Commands::GetSetupPIN::Type mRequest;
};

/*
 * Command Login
 */
class AccountLoginLogin : public ClusterCommand {
public:
    AccountLoginLogin()
        : ClusterCommand("login")
    {
        AddArgument("TempAccountIdentifier", &mRequest.tempAccountIdentifier);
        AddArgument("SetupPIN", &mRequest.setupPIN);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRAccountLoginClusterLoginParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.tempAccountIdentifier = [[NSString alloc] initWithBytes:mRequest.tempAccountIdentifier.data()
                                                                length:mRequest.tempAccountIdentifier.size()
                                                              encoding:NSUTF8StringEncoding];
        params.setupPIN = [[NSString alloc] initWithBytes:mRequest.setupPIN.data()
                                                   length:mRequest.setupPIN.size()
                                                 encoding:NSUTF8StringEncoding];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster loginWithParams:params
                          completion:^(NSError * _Nullable error) {
                              responsesNeeded--;
                              if (error != nil) {
                                  mError = error;
                                  LogNSError("Error", error);
                              }
                              if (responsesNeeded == 0) {
                                  SetCommandExitStatus(mError);
                              }
                          }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::AccountLogin::Commands::Login::Type mRequest;
};

/*
 * Command Logout
 */
class AccountLoginLogout : public ClusterCommand {
public:
    AccountLoginLogout()
        : ClusterCommand("logout")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRAccountLoginClusterLogoutParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster logoutWithParams:params
                           completion:^(NSError * _Nullable error) {
                               responsesNeeded--;
                               if (error != nil) {
                                   mError = error;
                                   LogNSError("Error", error);
                               }
                               if (responsesNeeded == 0) {
                                   SetCommandExitStatus(mError);
                               }
                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Attribute GeneratedCommandList
 */
class ReadAccountLoginGeneratedCommandList : public ReadAttribute {
public:
    ReadAccountLoginGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadAccountLoginGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccountLogin.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccountLogin GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccountLoginGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAccountLoginGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeAccountLoginGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccountLogin.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadAccountLoginAcceptedCommandList : public ReadAttribute {
public:
    ReadAccountLoginAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadAccountLoginAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccountLogin.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccountLogin AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccountLoginAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeAccountLoginAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeAccountLoginAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccountLogin.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadAccountLoginAttributeList : public ReadAttribute {
public:
    ReadAccountLoginAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadAccountLoginAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccountLogin.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccountLogin AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccountLoginAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeAccountLoginAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeAccountLoginAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccountLogin.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadAccountLoginFeatureMap : public ReadAttribute {
public:
    ReadAccountLoginFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadAccountLoginFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccountLogin.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("AccountLogin FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccountLoginFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeAccountLoginFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeAccountLoginFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccountLogin.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadAccountLoginClusterRevision : public ReadAttribute {
public:
    ReadAccountLoginClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadAccountLoginClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccountLogin.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("AccountLogin ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccountLoginClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeAccountLoginClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeAccountLoginClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccountLogin.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster ElectricalMeasurement                                       | 0x0B04 |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * GetProfileInfoCommand                                             |   0x00 |
| * GetMeasurementProfileCommand                                      |   0x01 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * MeasurementType                                                   | 0x0000 |
| * DcVoltage                                                         | 0x0100 |
| * DcVoltageMin                                                      | 0x0101 |
| * DcVoltageMax                                                      | 0x0102 |
| * DcCurrent                                                         | 0x0103 |
| * DcCurrentMin                                                      | 0x0104 |
| * DcCurrentMax                                                      | 0x0105 |
| * DcPower                                                           | 0x0106 |
| * DcPowerMin                                                        | 0x0107 |
| * DcPowerMax                                                        | 0x0108 |
| * DcVoltageMultiplier                                               | 0x0200 |
| * DcVoltageDivisor                                                  | 0x0201 |
| * DcCurrentMultiplier                                               | 0x0202 |
| * DcCurrentDivisor                                                  | 0x0203 |
| * DcPowerMultiplier                                                 | 0x0204 |
| * DcPowerDivisor                                                    | 0x0205 |
| * AcFrequency                                                       | 0x0300 |
| * AcFrequencyMin                                                    | 0x0301 |
| * AcFrequencyMax                                                    | 0x0302 |
| * NeutralCurrent                                                    | 0x0303 |
| * TotalActivePower                                                  | 0x0304 |
| * TotalReactivePower                                                | 0x0305 |
| * TotalApparentPower                                                | 0x0306 |
| * Measured1stHarmonicCurrent                                        | 0x0307 |
| * Measured3rdHarmonicCurrent                                        | 0x0308 |
| * Measured5thHarmonicCurrent                                        | 0x0309 |
| * Measured7thHarmonicCurrent                                        | 0x030A |
| * Measured9thHarmonicCurrent                                        | 0x030B |
| * Measured11thHarmonicCurrent                                       | 0x030C |
| * MeasuredPhase1stHarmonicCurrent                                   | 0x030D |
| * MeasuredPhase3rdHarmonicCurrent                                   | 0x030E |
| * MeasuredPhase5thHarmonicCurrent                                   | 0x030F |
| * MeasuredPhase7thHarmonicCurrent                                   | 0x0310 |
| * MeasuredPhase9thHarmonicCurrent                                   | 0x0311 |
| * MeasuredPhase11thHarmonicCurrent                                  | 0x0312 |
| * AcFrequencyMultiplier                                             | 0x0400 |
| * AcFrequencyDivisor                                                | 0x0401 |
| * PowerMultiplier                                                   | 0x0402 |
| * PowerDivisor                                                      | 0x0403 |
| * HarmonicCurrentMultiplier                                         | 0x0404 |
| * PhaseHarmonicCurrentMultiplier                                    | 0x0405 |
| * InstantaneousVoltage                                              | 0x0500 |
| * InstantaneousLineCurrent                                          | 0x0501 |
| * InstantaneousActiveCurrent                                        | 0x0502 |
| * InstantaneousReactiveCurrent                                      | 0x0503 |
| * InstantaneousPower                                                | 0x0504 |
| * RmsVoltage                                                        | 0x0505 |
| * RmsVoltageMin                                                     | 0x0506 |
| * RmsVoltageMax                                                     | 0x0507 |
| * RmsCurrent                                                        | 0x0508 |
| * RmsCurrentMin                                                     | 0x0509 |
| * RmsCurrentMax                                                     | 0x050A |
| * ActivePower                                                       | 0x050B |
| * ActivePowerMin                                                    | 0x050C |
| * ActivePowerMax                                                    | 0x050D |
| * ReactivePower                                                     | 0x050E |
| * ApparentPower                                                     | 0x050F |
| * PowerFactor                                                       | 0x0510 |
| * AverageRmsVoltageMeasurementPeriod                                | 0x0511 |
| * AverageRmsUnderVoltageCounter                                     | 0x0513 |
| * RmsExtremeOverVoltagePeriod                                       | 0x0514 |
| * RmsExtremeUnderVoltagePeriod                                      | 0x0515 |
| * RmsVoltageSagPeriod                                               | 0x0516 |
| * RmsVoltageSwellPeriod                                             | 0x0517 |
| * AcVoltageMultiplier                                               | 0x0600 |
| * AcVoltageDivisor                                                  | 0x0601 |
| * AcCurrentMultiplier                                               | 0x0602 |
| * AcCurrentDivisor                                                  | 0x0603 |
| * AcPowerMultiplier                                                 | 0x0604 |
| * AcPowerDivisor                                                    | 0x0605 |
| * OverloadAlarmsMask                                                | 0x0700 |
| * VoltageOverload                                                   | 0x0701 |
| * CurrentOverload                                                   | 0x0702 |
| * AcOverloadAlarmsMask                                              | 0x0800 |
| * AcVoltageOverload                                                 | 0x0801 |
| * AcCurrentOverload                                                 | 0x0802 |
| * AcActivePowerOverload                                             | 0x0803 |
| * AcReactivePowerOverload                                           | 0x0804 |
| * AverageRmsOverVoltage                                             | 0x0805 |
| * AverageRmsUnderVoltage                                            | 0x0806 |
| * RmsExtremeOverVoltage                                             | 0x0807 |
| * RmsExtremeUnderVoltage                                            | 0x0808 |
| * RmsVoltageSag                                                     | 0x0809 |
| * RmsVoltageSwell                                                   | 0x080A |
| * LineCurrentPhaseB                                                 | 0x0901 |
| * ActiveCurrentPhaseB                                               | 0x0902 |
| * ReactiveCurrentPhaseB                                             | 0x0903 |
| * RmsVoltagePhaseB                                                  | 0x0905 |
| * RmsVoltageMinPhaseB                                               | 0x0906 |
| * RmsVoltageMaxPhaseB                                               | 0x0907 |
| * RmsCurrentPhaseB                                                  | 0x0908 |
| * RmsCurrentMinPhaseB                                               | 0x0909 |
| * RmsCurrentMaxPhaseB                                               | 0x090A |
| * ActivePowerPhaseB                                                 | 0x090B |
| * ActivePowerMinPhaseB                                              | 0x090C |
| * ActivePowerMaxPhaseB                                              | 0x090D |
| * ReactivePowerPhaseB                                               | 0x090E |
| * ApparentPowerPhaseB                                               | 0x090F |
| * PowerFactorPhaseB                                                 | 0x0910 |
| * AverageRmsVoltageMeasurementPeriodPhaseB                          | 0x0911 |
| * AverageRmsOverVoltageCounterPhaseB                                | 0x0912 |
| * AverageRmsUnderVoltageCounterPhaseB                               | 0x0913 |
| * RmsExtremeOverVoltagePeriodPhaseB                                 | 0x0914 |
| * RmsExtremeUnderVoltagePeriodPhaseB                                | 0x0915 |
| * RmsVoltageSagPeriodPhaseB                                         | 0x0916 |
| * RmsVoltageSwellPeriodPhaseB                                       | 0x0917 |
| * LineCurrentPhaseC                                                 | 0x0A01 |
| * ActiveCurrentPhaseC                                               | 0x0A02 |
| * ReactiveCurrentPhaseC                                             | 0x0A03 |
| * RmsVoltagePhaseC                                                  | 0x0A05 |
| * RmsVoltageMinPhaseC                                               | 0x0A06 |
| * RmsVoltageMaxPhaseC                                               | 0x0A07 |
| * RmsCurrentPhaseC                                                  | 0x0A08 |
| * RmsCurrentMinPhaseC                                               | 0x0A09 |
| * RmsCurrentMaxPhaseC                                               | 0x0A0A |
| * ActivePowerPhaseC                                                 | 0x0A0B |
| * ActivePowerMinPhaseC                                              | 0x0A0C |
| * ActivePowerMaxPhaseC                                              | 0x0A0D |
| * ReactivePowerPhaseC                                               | 0x0A0E |
| * ApparentPowerPhaseC                                               | 0x0A0F |
| * PowerFactorPhaseC                                                 | 0x0A10 |
| * AverageRmsVoltageMeasurementPeriodPhaseC                          | 0x0A11 |
| * AverageRmsOverVoltageCounterPhaseC                                | 0x0A12 |
| * AverageRmsUnderVoltageCounterPhaseC                               | 0x0A13 |
| * RmsExtremeOverVoltagePeriodPhaseC                                 | 0x0A14 |
| * RmsExtremeUnderVoltagePeriodPhaseC                                | 0x0A15 |
| * RmsVoltageSagPeriodPhaseC                                         | 0x0A16 |
| * RmsVoltageSwellPeriodPhaseC                                       | 0x0A17 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Command GetProfileInfoCommand
 */
class ElectricalMeasurementGetProfileInfoCommand : public ClusterCommand {
public:
    ElectricalMeasurementGetProfileInfoCommand()
        : ClusterCommand("get-profile-info-command")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRElectricalMeasurementClusterGetProfileInfoCommandParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getProfileInfoCommandWithParams:params
                                          completion:^(NSError * _Nullable error) {
                                              responsesNeeded--;
                                              if (error != nil) {
                                                  mError = error;
                                                  LogNSError("Error", error);
                                              }
                                              if (responsesNeeded == 0) {
                                                  SetCommandExitStatus(mError);
                                              }
                                          }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command GetMeasurementProfileCommand
 */
class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand {
public:
    ElectricalMeasurementGetMeasurementProfileCommand()
        : ClusterCommand("get-measurement-profile-command")
    {
        AddArgument("AttributeId", 0, UINT16_MAX, &mRequest.attributeId);
        AddArgument("StartTime", 0, UINT32_MAX, &mRequest.startTime);
        AddArgument("NumberOfIntervals", 0, UINT8_MAX, &mRequest.numberOfIntervals);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRElectricalMeasurementClusterGetMeasurementProfileCommandParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.attributeId = [NSNumber numberWithUnsignedShort:mRequest.attributeId];
        params.startTime = [NSNumber numberWithUnsignedInt:mRequest.startTime];
        params.numberOfIntervals = [NSNumber numberWithUnsignedChar:mRequest.numberOfIntervals];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster getMeasurementProfileCommandWithParams:params
                                                 completion:^(NSError * _Nullable error) {
                                                     responsesNeeded--;
                                                     if (error != nil) {
                                                         mError = error;
                                                         LogNSError("Error", error);
                                                     }
                                                     if (responsesNeeded == 0) {
                                                         SetCommandExitStatus(mError);
                                                     }
                                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::ElectricalMeasurement::Commands::GetMeasurementProfileCommand::Type mRequest;
};

/*
 * Attribute MeasurementType
 */
class ReadElectricalMeasurementMeasurementType : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasurementType()
        : ReadAttribute("measurement-type")
    {
    }

    ~ReadElectricalMeasurementMeasurementType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeMeasurementTypeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.MeasurementType response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement MeasurementType read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasurementType : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasurementType()
        : SubscribeAttribute("measurement-type")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasurementType() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasurementTypeWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasurementType response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcVoltage
 */
class ReadElectricalMeasurementDcVoltage : public ReadAttribute {
public:
    ReadElectricalMeasurementDcVoltage()
        : ReadAttribute("dc-voltage")
    {
    }

    ~ReadElectricalMeasurementDcVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000100) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcVoltage : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcVoltage()
        : SubscribeAttribute("dc-voltage")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000100) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcVoltageMin
 */
class ReadElectricalMeasurementDcVoltageMin : public ReadAttribute {
public:
    ReadElectricalMeasurementDcVoltageMin()
        : ReadAttribute("dc-voltage-min")
    {
    }

    ~ReadElectricalMeasurementDcVoltageMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000101) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcVoltageMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcVoltageMin response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcVoltageMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcVoltageMin : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcVoltageMin()
        : SubscribeAttribute("dc-voltage-min")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcVoltageMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000101) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcVoltageMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcVoltageMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcVoltageMax
 */
class ReadElectricalMeasurementDcVoltageMax : public ReadAttribute {
public:
    ReadElectricalMeasurementDcVoltageMax()
        : ReadAttribute("dc-voltage-max")
    {
    }

    ~ReadElectricalMeasurementDcVoltageMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000102) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcVoltageMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcVoltageMax response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcVoltageMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcVoltageMax : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcVoltageMax()
        : SubscribeAttribute("dc-voltage-max")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcVoltageMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000102) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcVoltageMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcVoltageMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcCurrent
 */
class ReadElectricalMeasurementDcCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementDcCurrent()
        : ReadAttribute("dc-current")
    {
    }

    ~ReadElectricalMeasurementDcCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000103) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcCurrent()
        : SubscribeAttribute("dc-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000103) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcCurrentMin
 */
class ReadElectricalMeasurementDcCurrentMin : public ReadAttribute {
public:
    ReadElectricalMeasurementDcCurrentMin()
        : ReadAttribute("dc-current-min")
    {
    }

    ~ReadElectricalMeasurementDcCurrentMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000104) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcCurrentMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcCurrentMin response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcCurrentMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcCurrentMin : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcCurrentMin()
        : SubscribeAttribute("dc-current-min")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcCurrentMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000104) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcCurrentMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcCurrentMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcCurrentMax
 */
class ReadElectricalMeasurementDcCurrentMax : public ReadAttribute {
public:
    ReadElectricalMeasurementDcCurrentMax()
        : ReadAttribute("dc-current-max")
    {
    }

    ~ReadElectricalMeasurementDcCurrentMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000105) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcCurrentMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcCurrentMax response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcCurrentMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcCurrentMax : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcCurrentMax()
        : SubscribeAttribute("dc-current-max")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcCurrentMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000105) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcCurrentMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcCurrentMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcPower
 */
class ReadElectricalMeasurementDcPower : public ReadAttribute {
public:
    ReadElectricalMeasurementDcPower()
        : ReadAttribute("dc-power")
    {
    }

    ~ReadElectricalMeasurementDcPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000106) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcPower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcPower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcPower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcPower()
        : SubscribeAttribute("dc-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000106) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcPowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcPower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcPowerMin
 */
class ReadElectricalMeasurementDcPowerMin : public ReadAttribute {
public:
    ReadElectricalMeasurementDcPowerMin()
        : ReadAttribute("dc-power-min")
    {
    }

    ~ReadElectricalMeasurementDcPowerMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000107) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcPowerMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcPowerMin response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcPowerMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcPowerMin : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcPowerMin()
        : SubscribeAttribute("dc-power-min")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcPowerMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000107) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcPowerMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcPowerMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcPowerMax
 */
class ReadElectricalMeasurementDcPowerMax : public ReadAttribute {
public:
    ReadElectricalMeasurementDcPowerMax()
        : ReadAttribute("dc-power-max")
    {
    }

    ~ReadElectricalMeasurementDcPowerMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000108) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcPowerMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcPowerMax response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcPowerMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcPowerMax : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcPowerMax()
        : SubscribeAttribute("dc-power-max")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcPowerMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000108) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcPowerMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcPowerMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcVoltageMultiplier
 */
class ReadElectricalMeasurementDcVoltageMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementDcVoltageMultiplier()
        : ReadAttribute("dc-voltage-multiplier")
    {
    }

    ~ReadElectricalMeasurementDcVoltageMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000200) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcVoltageMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcVoltageMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcVoltageMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcVoltageMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcVoltageMultiplier()
        : SubscribeAttribute("dc-voltage-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcVoltageMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000200) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcVoltageMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcVoltageMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcVoltageDivisor
 */
class ReadElectricalMeasurementDcVoltageDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementDcVoltageDivisor()
        : ReadAttribute("dc-voltage-divisor")
    {
    }

    ~ReadElectricalMeasurementDcVoltageDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000201) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcVoltageDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcVoltageDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcVoltageDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcVoltageDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcVoltageDivisor()
        : SubscribeAttribute("dc-voltage-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcVoltageDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000201) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcVoltageDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcVoltageDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcCurrentMultiplier
 */
class ReadElectricalMeasurementDcCurrentMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementDcCurrentMultiplier()
        : ReadAttribute("dc-current-multiplier")
    {
    }

    ~ReadElectricalMeasurementDcCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000202) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcCurrentMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcCurrentMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcCurrentMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcCurrentMultiplier()
        : SubscribeAttribute("dc-current-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000202) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcCurrentMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcCurrentMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcCurrentDivisor
 */
class ReadElectricalMeasurementDcCurrentDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementDcCurrentDivisor()
        : ReadAttribute("dc-current-divisor")
    {
    }

    ~ReadElectricalMeasurementDcCurrentDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000203) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcCurrentDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcCurrentDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcCurrentDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcCurrentDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcCurrentDivisor()
        : SubscribeAttribute("dc-current-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcCurrentDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000203) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcCurrentDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcCurrentDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcPowerMultiplier
 */
class ReadElectricalMeasurementDcPowerMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementDcPowerMultiplier()
        : ReadAttribute("dc-power-multiplier")
    {
    }

    ~ReadElectricalMeasurementDcPowerMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000204) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcPowerMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcPowerMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcPowerMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcPowerMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcPowerMultiplier()
        : SubscribeAttribute("dc-power-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcPowerMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000204) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcPowerMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcPowerMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DcPowerDivisor
 */
class ReadElectricalMeasurementDcPowerDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementDcPowerDivisor()
        : ReadAttribute("dc-power-divisor")
    {
    }

    ~ReadElectricalMeasurementDcPowerDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000205) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeDcPowerDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.DcPowerDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement DcPowerDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementDcPowerDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementDcPowerDivisor()
        : SubscribeAttribute("dc-power-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementDcPowerDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000205) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeDcPowerDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.DcPowerDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcFrequency
 */
class ReadElectricalMeasurementAcFrequency : public ReadAttribute {
public:
    ReadElectricalMeasurementAcFrequency()
        : ReadAttribute("ac-frequency")
    {
    }

    ~ReadElectricalMeasurementAcFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000300) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcFrequencyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcFrequency response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcFrequency read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcFrequency : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcFrequency()
        : SubscribeAttribute("ac-frequency")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcFrequency() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000300) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcFrequencyWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcFrequency response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcFrequencyMin
 */
class ReadElectricalMeasurementAcFrequencyMin : public ReadAttribute {
public:
    ReadElectricalMeasurementAcFrequencyMin()
        : ReadAttribute("ac-frequency-min")
    {
    }

    ~ReadElectricalMeasurementAcFrequencyMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000301) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcFrequencyMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcFrequencyMin response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcFrequencyMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcFrequencyMin : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcFrequencyMin()
        : SubscribeAttribute("ac-frequency-min")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcFrequencyMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000301) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcFrequencyMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcFrequencyMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcFrequencyMax
 */
class ReadElectricalMeasurementAcFrequencyMax : public ReadAttribute {
public:
    ReadElectricalMeasurementAcFrequencyMax()
        : ReadAttribute("ac-frequency-max")
    {
    }

    ~ReadElectricalMeasurementAcFrequencyMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000302) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcFrequencyMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcFrequencyMax response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcFrequencyMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcFrequencyMax : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcFrequencyMax()
        : SubscribeAttribute("ac-frequency-max")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcFrequencyMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000302) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcFrequencyMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcFrequencyMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NeutralCurrent
 */
class ReadElectricalMeasurementNeutralCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementNeutralCurrent()
        : ReadAttribute("neutral-current")
    {
    }

    ~ReadElectricalMeasurementNeutralCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000303) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeNeutralCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.NeutralCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement NeutralCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementNeutralCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementNeutralCurrent()
        : SubscribeAttribute("neutral-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementNeutralCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000303) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNeutralCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.NeutralCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TotalActivePower
 */
class ReadElectricalMeasurementTotalActivePower : public ReadAttribute {
public:
    ReadElectricalMeasurementTotalActivePower()
        : ReadAttribute("total-active-power")
    {
    }

    ~ReadElectricalMeasurementTotalActivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000304) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeTotalActivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.TotalActivePower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement TotalActivePower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementTotalActivePower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementTotalActivePower()
        : SubscribeAttribute("total-active-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementTotalActivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000304) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTotalActivePowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.TotalActivePower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TotalReactivePower
 */
class ReadElectricalMeasurementTotalReactivePower : public ReadAttribute {
public:
    ReadElectricalMeasurementTotalReactivePower()
        : ReadAttribute("total-reactive-power")
    {
    }

    ~ReadElectricalMeasurementTotalReactivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000305) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeTotalReactivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.TotalReactivePower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement TotalReactivePower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementTotalReactivePower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementTotalReactivePower()
        : SubscribeAttribute("total-reactive-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementTotalReactivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000305) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTotalReactivePowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.TotalReactivePower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TotalApparentPower
 */
class ReadElectricalMeasurementTotalApparentPower : public ReadAttribute {
public:
    ReadElectricalMeasurementTotalApparentPower()
        : ReadAttribute("total-apparent-power")
    {
    }

    ~ReadElectricalMeasurementTotalApparentPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000306) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeTotalApparentPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.TotalApparentPower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement TotalApparentPower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementTotalApparentPower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementTotalApparentPower()
        : SubscribeAttribute("total-apparent-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementTotalApparentPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000306) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTotalApparentPowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.TotalApparentPower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Measured1stHarmonicCurrent
 */
class ReadElectricalMeasurementMeasured1stHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasured1stHarmonicCurrent()
        : ReadAttribute("measured1st-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasured1stHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000307) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeMeasured1stHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.Measured1stHarmonicCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement Measured1stHarmonicCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasured1stHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasured1stHarmonicCurrent()
        : SubscribeAttribute("measured1st-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasured1stHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000307) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasured1stHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.Measured1stHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Measured3rdHarmonicCurrent
 */
class ReadElectricalMeasurementMeasured3rdHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasured3rdHarmonicCurrent()
        : ReadAttribute("measured3rd-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasured3rdHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000308) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeMeasured3rdHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.Measured3rdHarmonicCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement Measured3rdHarmonicCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasured3rdHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasured3rdHarmonicCurrent()
        : SubscribeAttribute("measured3rd-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasured3rdHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000308) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasured3rdHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.Measured3rdHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Measured5thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasured5thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasured5thHarmonicCurrent()
        : ReadAttribute("measured5th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasured5thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000309) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeMeasured5thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.Measured5thHarmonicCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement Measured5thHarmonicCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasured5thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasured5thHarmonicCurrent()
        : SubscribeAttribute("measured5th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasured5thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000309) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasured5thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.Measured5thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Measured7thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasured7thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasured7thHarmonicCurrent()
        : ReadAttribute("measured7th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasured7thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000030A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeMeasured7thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.Measured7thHarmonicCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement Measured7thHarmonicCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasured7thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasured7thHarmonicCurrent()
        : SubscribeAttribute("measured7th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasured7thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000030A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasured7thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.Measured7thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Measured9thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasured9thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasured9thHarmonicCurrent()
        : ReadAttribute("measured9th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasured9thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000030B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeMeasured9thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.Measured9thHarmonicCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement Measured9thHarmonicCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasured9thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasured9thHarmonicCurrent()
        : SubscribeAttribute("measured9th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasured9thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000030B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasured9thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.Measured9thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Measured11thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasured11thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasured11thHarmonicCurrent()
        : ReadAttribute("measured11th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasured11thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000030C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeMeasured11thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.Measured11thHarmonicCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement Measured11thHarmonicCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasured11thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasured11thHarmonicCurrent()
        : SubscribeAttribute("measured11th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasured11thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000030C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasured11thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.Measured11thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MeasuredPhase1stHarmonicCurrent
 */
class ReadElectricalMeasurementMeasuredPhase1stHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasuredPhase1stHarmonicCurrent()
        : ReadAttribute("measured-phase1st-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasuredPhase1stHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000030D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeMeasuredPhase1stHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase1stHarmonicCurrent response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement MeasuredPhase1stHarmonicCurrent read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasuredPhase1stHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasuredPhase1stHarmonicCurrent()
        : SubscribeAttribute("measured-phase1st-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasuredPhase1stHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000030D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredPhase1stHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase1stHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MeasuredPhase3rdHarmonicCurrent
 */
class ReadElectricalMeasurementMeasuredPhase3rdHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasuredPhase3rdHarmonicCurrent()
        : ReadAttribute("measured-phase3rd-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasuredPhase3rdHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000030E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeMeasuredPhase3rdHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase3rdHarmonicCurrent response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement MeasuredPhase3rdHarmonicCurrent read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasuredPhase3rdHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasuredPhase3rdHarmonicCurrent()
        : SubscribeAttribute("measured-phase3rd-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasuredPhase3rdHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000030E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredPhase3rdHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase3rdHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MeasuredPhase5thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasuredPhase5thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasuredPhase5thHarmonicCurrent()
        : ReadAttribute("measured-phase5th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasuredPhase5thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000030F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeMeasuredPhase5thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase5thHarmonicCurrent response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement MeasuredPhase5thHarmonicCurrent read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasuredPhase5thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasuredPhase5thHarmonicCurrent()
        : SubscribeAttribute("measured-phase5th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasuredPhase5thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000030F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredPhase5thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase5thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MeasuredPhase7thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasuredPhase7thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasuredPhase7thHarmonicCurrent()
        : ReadAttribute("measured-phase7th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasuredPhase7thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000310) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeMeasuredPhase7thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase7thHarmonicCurrent response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement MeasuredPhase7thHarmonicCurrent read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasuredPhase7thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasuredPhase7thHarmonicCurrent()
        : SubscribeAttribute("measured-phase7th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasuredPhase7thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000310) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredPhase7thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase7thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MeasuredPhase9thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasuredPhase9thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasuredPhase9thHarmonicCurrent()
        : ReadAttribute("measured-phase9th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasuredPhase9thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000311) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeMeasuredPhase9thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase9thHarmonicCurrent response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement MeasuredPhase9thHarmonicCurrent read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasuredPhase9thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasuredPhase9thHarmonicCurrent()
        : SubscribeAttribute("measured-phase9th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasuredPhase9thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000311) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredPhase9thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase9thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute MeasuredPhase11thHarmonicCurrent
 */
class ReadElectricalMeasurementMeasuredPhase11thHarmonicCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementMeasuredPhase11thHarmonicCurrent()
        : ReadAttribute("measured-phase11th-harmonic-current")
    {
    }

    ~ReadElectricalMeasurementMeasuredPhase11thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000312) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeMeasuredPhase11thHarmonicCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase11thHarmonicCurrent response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement MeasuredPhase11thHarmonicCurrent read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementMeasuredPhase11thHarmonicCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementMeasuredPhase11thHarmonicCurrent()
        : SubscribeAttribute("measured-phase11th-harmonic-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementMeasuredPhase11thHarmonicCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000312) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeMeasuredPhase11thHarmonicCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.MeasuredPhase11thHarmonicCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcFrequencyMultiplier
 */
class ReadElectricalMeasurementAcFrequencyMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementAcFrequencyMultiplier()
        : ReadAttribute("ac-frequency-multiplier")
    {
    }

    ~ReadElectricalMeasurementAcFrequencyMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000400) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcFrequencyMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcFrequencyMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcFrequencyMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcFrequencyMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcFrequencyMultiplier()
        : SubscribeAttribute("ac-frequency-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcFrequencyMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000400) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcFrequencyMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcFrequencyMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcFrequencyDivisor
 */
class ReadElectricalMeasurementAcFrequencyDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementAcFrequencyDivisor()
        : ReadAttribute("ac-frequency-divisor")
    {
    }

    ~ReadElectricalMeasurementAcFrequencyDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000401) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcFrequencyDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcFrequencyDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcFrequencyDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcFrequencyDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcFrequencyDivisor()
        : SubscribeAttribute("ac-frequency-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcFrequencyDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000401) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcFrequencyDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcFrequencyDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PowerMultiplier
 */
class ReadElectricalMeasurementPowerMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementPowerMultiplier()
        : ReadAttribute("power-multiplier")
    {
    }

    ~ReadElectricalMeasurementPowerMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000402) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributePowerMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.PowerMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement PowerMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementPowerMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementPowerMultiplier()
        : SubscribeAttribute("power-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementPowerMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000402) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePowerMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.PowerMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PowerDivisor
 */
class ReadElectricalMeasurementPowerDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementPowerDivisor()
        : ReadAttribute("power-divisor")
    {
    }

    ~ReadElectricalMeasurementPowerDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000403) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributePowerDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.PowerDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement PowerDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementPowerDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementPowerDivisor()
        : SubscribeAttribute("power-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementPowerDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000403) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePowerDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.PowerDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute HarmonicCurrentMultiplier
 */
class ReadElectricalMeasurementHarmonicCurrentMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementHarmonicCurrentMultiplier()
        : ReadAttribute("harmonic-current-multiplier")
    {
    }

    ~ReadElectricalMeasurementHarmonicCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000404) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeHarmonicCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.HarmonicCurrentMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement HarmonicCurrentMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementHarmonicCurrentMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementHarmonicCurrentMultiplier()
        : SubscribeAttribute("harmonic-current-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementHarmonicCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000404) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeHarmonicCurrentMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.HarmonicCurrentMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PhaseHarmonicCurrentMultiplier
 */
class ReadElectricalMeasurementPhaseHarmonicCurrentMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementPhaseHarmonicCurrentMultiplier()
        : ReadAttribute("phase-harmonic-current-multiplier")
    {
    }

    ~ReadElectricalMeasurementPhaseHarmonicCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000405) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributePhaseHarmonicCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.PhaseHarmonicCurrentMultiplier response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement PhaseHarmonicCurrentMultiplier read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementPhaseHarmonicCurrentMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementPhaseHarmonicCurrentMultiplier()
        : SubscribeAttribute("phase-harmonic-current-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementPhaseHarmonicCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000405) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePhaseHarmonicCurrentMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.PhaseHarmonicCurrentMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstantaneousVoltage
 */
class ReadElectricalMeasurementInstantaneousVoltage : public ReadAttribute {
public:
    ReadElectricalMeasurementInstantaneousVoltage()
        : ReadAttribute("instantaneous-voltage")
    {
    }

    ~ReadElectricalMeasurementInstantaneousVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000500) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeInstantaneousVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.InstantaneousVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement InstantaneousVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementInstantaneousVoltage : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementInstantaneousVoltage()
        : SubscribeAttribute("instantaneous-voltage")
    {
    }

    ~SubscribeAttributeElectricalMeasurementInstantaneousVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000500) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstantaneousVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.InstantaneousVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstantaneousLineCurrent
 */
class ReadElectricalMeasurementInstantaneousLineCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementInstantaneousLineCurrent()
        : ReadAttribute("instantaneous-line-current")
    {
    }

    ~ReadElectricalMeasurementInstantaneousLineCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000501) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeInstantaneousLineCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.InstantaneousLineCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement InstantaneousLineCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementInstantaneousLineCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementInstantaneousLineCurrent()
        : SubscribeAttribute("instantaneous-line-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementInstantaneousLineCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000501) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstantaneousLineCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.InstantaneousLineCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstantaneousActiveCurrent
 */
class ReadElectricalMeasurementInstantaneousActiveCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementInstantaneousActiveCurrent()
        : ReadAttribute("instantaneous-active-current")
    {
    }

    ~ReadElectricalMeasurementInstantaneousActiveCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000502) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeInstantaneousActiveCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.InstantaneousActiveCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement InstantaneousActiveCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementInstantaneousActiveCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementInstantaneousActiveCurrent()
        : SubscribeAttribute("instantaneous-active-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementInstantaneousActiveCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000502) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstantaneousActiveCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.InstantaneousActiveCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstantaneousReactiveCurrent
 */
class ReadElectricalMeasurementInstantaneousReactiveCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementInstantaneousReactiveCurrent()
        : ReadAttribute("instantaneous-reactive-current")
    {
    }

    ~ReadElectricalMeasurementInstantaneousReactiveCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000503) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeInstantaneousReactiveCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.InstantaneousReactiveCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement InstantaneousReactiveCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementInstantaneousReactiveCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementInstantaneousReactiveCurrent()
        : SubscribeAttribute("instantaneous-reactive-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementInstantaneousReactiveCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000503) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstantaneousReactiveCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.InstantaneousReactiveCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InstantaneousPower
 */
class ReadElectricalMeasurementInstantaneousPower : public ReadAttribute {
public:
    ReadElectricalMeasurementInstantaneousPower()
        : ReadAttribute("instantaneous-power")
    {
    }

    ~ReadElectricalMeasurementInstantaneousPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000504) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeInstantaneousPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.InstantaneousPower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement InstantaneousPower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementInstantaneousPower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementInstantaneousPower()
        : SubscribeAttribute("instantaneous-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementInstantaneousPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000504) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInstantaneousPowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.InstantaneousPower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltage
 */
class ReadElectricalMeasurementRmsVoltage : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltage()
        : ReadAttribute("rms-voltage")
    {
    }

    ~ReadElectricalMeasurementRmsVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000505) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltage : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltage()
        : SubscribeAttribute("rms-voltage")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000505) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageMin
 */
class ReadElectricalMeasurementRmsVoltageMin : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageMin()
        : ReadAttribute("rms-voltage-min")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000506) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageMin response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageMin : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageMin()
        : SubscribeAttribute("rms-voltage-min")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000506) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageMax
 */
class ReadElectricalMeasurementRmsVoltageMax : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageMax()
        : ReadAttribute("rms-voltage-max")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000507) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageMax response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageMax : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageMax()
        : SubscribeAttribute("rms-voltage-max")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000507) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrent
 */
class ReadElectricalMeasurementRmsCurrent : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrent()
        : ReadAttribute("rms-current")
    {
    }

    ~ReadElectricalMeasurementRmsCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000508) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrent response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrent read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrent : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrent()
        : SubscribeAttribute("rms-current")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrent() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000508) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrent response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentMin
 */
class ReadElectricalMeasurementRmsCurrentMin : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentMin()
        : ReadAttribute("rms-current-min")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000509) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentMin response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentMin : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentMin()
        : SubscribeAttribute("rms-current-min")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000509) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentMax
 */
class ReadElectricalMeasurementRmsCurrentMax : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentMax()
        : ReadAttribute("rms-current-max")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000050A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentMax response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentMax : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentMax()
        : SubscribeAttribute("rms-current-max")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000050A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePower
 */
class ReadElectricalMeasurementActivePower : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePower()
        : ReadAttribute("active-power")
    {
    }

    ~ReadElectricalMeasurementActivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000050B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePower()
        : SubscribeAttribute("active-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000050B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerMin
 */
class ReadElectricalMeasurementActivePowerMin : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerMin()
        : ReadAttribute("active-power-min")
    {
    }

    ~ReadElectricalMeasurementActivePowerMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000050C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerMinWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerMin response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerMin read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerMin : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerMin()
        : SubscribeAttribute("active-power-min")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerMin() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000050C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerMinWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerMin response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerMax
 */
class ReadElectricalMeasurementActivePowerMax : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerMax()
        : ReadAttribute("active-power-max")
    {
    }

    ~ReadElectricalMeasurementActivePowerMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000050D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerMaxWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerMax response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerMax read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerMax : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerMax()
        : SubscribeAttribute("active-power-max")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerMax() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000050D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerMaxWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerMax response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ReactivePower
 */
class ReadElectricalMeasurementReactivePower : public ReadAttribute {
public:
    ReadElectricalMeasurementReactivePower()
        : ReadAttribute("reactive-power")
    {
    }

    ~ReadElectricalMeasurementReactivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000050E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeReactivePowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ReactivePower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ReactivePower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementReactivePower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementReactivePower()
        : SubscribeAttribute("reactive-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementReactivePower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000050E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReactivePowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ReactivePower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ApparentPower
 */
class ReadElectricalMeasurementApparentPower : public ReadAttribute {
public:
    ReadElectricalMeasurementApparentPower()
        : ReadAttribute("apparent-power")
    {
    }

    ~ReadElectricalMeasurementApparentPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000050F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeApparentPowerWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ApparentPower response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ApparentPower read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementApparentPower : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementApparentPower()
        : SubscribeAttribute("apparent-power")
    {
    }

    ~SubscribeAttributeElectricalMeasurementApparentPower() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000050F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeApparentPowerWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ApparentPower response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PowerFactor
 */
class ReadElectricalMeasurementPowerFactor : public ReadAttribute {
public:
    ReadElectricalMeasurementPowerFactor()
        : ReadAttribute("power-factor")
    {
    }

    ~ReadElectricalMeasurementPowerFactor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000510) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributePowerFactorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.PowerFactor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement PowerFactor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementPowerFactor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementPowerFactor()
        : SubscribeAttribute("power-factor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementPowerFactor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000510) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePowerFactorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.PowerFactor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsVoltageMeasurementPeriod
 */
class ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriod : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriod()
        : ReadAttribute("average-rms-voltage-measurement-period")
    {
    }

    ~ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000511) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeAverageRmsVoltageMeasurementPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsVoltageMeasurementPeriod response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement AverageRmsVoltageMeasurementPeriod read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementAverageRmsVoltageMeasurementPeriod : public WriteAttribute {
public:
    WriteElectricalMeasurementAverageRmsVoltageMeasurementPeriod()
        : WriteAttribute("average-rms-voltage-measurement-period")
    {
        AddArgument("attr-name", "average-rms-voltage-measurement-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementAverageRmsVoltageMeasurementPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000511) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:value
                                                                    params:params
                                                                completion:^(NSError * _Nullable error) {
                                                                    if (error != nil) {
                                                                        LogNSError("ElectricalMeasurement "
                                                                                   "AverageRmsVoltageMeasurementPeriod write Error",
                                                                            error);
                                                                    }
                                                                    SetCommandExitStatus(error);
                                                                }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriod : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriod()
        : SubscribeAttribute("average-rms-voltage-measurement-period")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000511) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsVoltageMeasurementPeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsVoltageMeasurementPeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsUnderVoltageCounter
 */
class ReadElectricalMeasurementAverageRmsUnderVoltageCounter : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsUnderVoltageCounter()
        : ReadAttribute("average-rms-under-voltage-counter")
    {
    }

    ~ReadElectricalMeasurementAverageRmsUnderVoltageCounter() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000513) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAverageRmsUnderVoltageCounterWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltageCounter response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AverageRmsUnderVoltageCounter read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementAverageRmsUnderVoltageCounter : public WriteAttribute {
public:
    WriteElectricalMeasurementAverageRmsUnderVoltageCounter()
        : WriteAttribute("average-rms-under-voltage-counter")
    {
        AddArgument("attr-name", "average-rms-under-voltage-counter");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementAverageRmsUnderVoltageCounter() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000513) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeAverageRmsUnderVoltageCounterWithValue:value
                                                          params:params
                                                      completion:^(NSError * _Nullable error) {
                                                          if (error != nil) {
                                                              LogNSError(
                                                                  "ElectricalMeasurement AverageRmsUnderVoltageCounter write Error",
                                                                  error);
                                                          }
                                                          SetCommandExitStatus(error);
                                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounter : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounter()
        : SubscribeAttribute("average-rms-under-voltage-counter")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounter() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000513) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsUnderVoltageCounterWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltageCounter response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeOverVoltagePeriod
 */
class ReadElectricalMeasurementRmsExtremeOverVoltagePeriod : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeOverVoltagePeriod()
        : ReadAttribute("rms-extreme-over-voltage-period")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeOverVoltagePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000514) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsExtremeOverVoltagePeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltagePeriod response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsExtremeOverVoltagePeriod read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementRmsExtremeOverVoltagePeriod : public WriteAttribute {
public:
    WriteElectricalMeasurementRmsExtremeOverVoltagePeriod()
        : WriteAttribute("rms-extreme-over-voltage-period")
    {
        AddArgument("attr-name", "rms-extreme-over-voltage-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementRmsExtremeOverVoltagePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000514) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeRmsExtremeOverVoltagePeriodWithValue:value
                                                        params:params
                                                    completion:^(NSError * _Nullable error) {
                                                        if (error != nil) {
                                                            LogNSError(
                                                                "ElectricalMeasurement RmsExtremeOverVoltagePeriod write Error",
                                                                error);
                                                        }
                                                        SetCommandExitStatus(error);
                                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriod : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriod()
        : SubscribeAttribute("rms-extreme-over-voltage-period")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000514) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeOverVoltagePeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltagePeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeUnderVoltagePeriod
 */
class ReadElectricalMeasurementRmsExtremeUnderVoltagePeriod : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeUnderVoltagePeriod()
        : ReadAttribute("rms-extreme-under-voltage-period")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeUnderVoltagePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000515) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsExtremeUnderVoltagePeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltagePeriod response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsExtremeUnderVoltagePeriod read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementRmsExtremeUnderVoltagePeriod : public WriteAttribute {
public:
    WriteElectricalMeasurementRmsExtremeUnderVoltagePeriod()
        : WriteAttribute("rms-extreme-under-voltage-period")
    {
        AddArgument("attr-name", "rms-extreme-under-voltage-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementRmsExtremeUnderVoltagePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000515) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeRmsExtremeUnderVoltagePeriodWithValue:value
                                                         params:params
                                                     completion:^(NSError * _Nullable error) {
                                                         if (error != nil) {
                                                             LogNSError(
                                                                 "ElectricalMeasurement RmsExtremeUnderVoltagePeriod write Error",
                                                                 error);
                                                         }
                                                         SetCommandExitStatus(error);
                                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriod : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriod()
        : SubscribeAttribute("rms-extreme-under-voltage-period")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000515) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeUnderVoltagePeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltagePeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSagPeriod
 */
class ReadElectricalMeasurementRmsVoltageSagPeriod : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSagPeriod()
        : ReadAttribute("rms-voltage-sag-period")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSagPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000516) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSagPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSagPeriod response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSagPeriod read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementRmsVoltageSagPeriod : public WriteAttribute {
public:
    WriteElectricalMeasurementRmsVoltageSagPeriod()
        : WriteAttribute("rms-voltage-sag-period")
    {
        AddArgument("attr-name", "rms-voltage-sag-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementRmsVoltageSagPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000516) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeRmsVoltageSagPeriodWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("ElectricalMeasurement RmsVoltageSagPeriod write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriod : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriod()
        : SubscribeAttribute("rms-voltage-sag-period")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000516) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSagPeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSagPeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSwellPeriod
 */
class ReadElectricalMeasurementRmsVoltageSwellPeriod : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSwellPeriod()
        : ReadAttribute("rms-voltage-swell-period")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSwellPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000517) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSwellPeriodWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSwellPeriod response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSwellPeriod read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementRmsVoltageSwellPeriod : public WriteAttribute {
public:
    WriteElectricalMeasurementRmsVoltageSwellPeriod()
        : WriteAttribute("rms-voltage-swell-period")
    {
        AddArgument("attr-name", "rms-voltage-swell-period");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementRmsVoltageSwellPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000517) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeRmsVoltageSwellPeriodWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("ElectricalMeasurement RmsVoltageSwellPeriod write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriod : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriod()
        : SubscribeAttribute("rms-voltage-swell-period")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriod() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000517) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSwellPeriodWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSwellPeriod response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcVoltageMultiplier
 */
class ReadElectricalMeasurementAcVoltageMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementAcVoltageMultiplier()
        : ReadAttribute("ac-voltage-multiplier")
    {
    }

    ~ReadElectricalMeasurementAcVoltageMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000600) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcVoltageMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcVoltageMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcVoltageMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcVoltageMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcVoltageMultiplier()
        : SubscribeAttribute("ac-voltage-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcVoltageMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000600) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcVoltageMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcVoltageMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcVoltageDivisor
 */
class ReadElectricalMeasurementAcVoltageDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementAcVoltageDivisor()
        : ReadAttribute("ac-voltage-divisor")
    {
    }

    ~ReadElectricalMeasurementAcVoltageDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000601) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcVoltageDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcVoltageDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcVoltageDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcVoltageDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcVoltageDivisor()
        : SubscribeAttribute("ac-voltage-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcVoltageDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000601) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcVoltageDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcVoltageDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcCurrentMultiplier
 */
class ReadElectricalMeasurementAcCurrentMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementAcCurrentMultiplier()
        : ReadAttribute("ac-current-multiplier")
    {
    }

    ~ReadElectricalMeasurementAcCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000602) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcCurrentMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcCurrentMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcCurrentMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcCurrentMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcCurrentMultiplier()
        : SubscribeAttribute("ac-current-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcCurrentMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000602) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcCurrentMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcCurrentMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcCurrentDivisor
 */
class ReadElectricalMeasurementAcCurrentDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementAcCurrentDivisor()
        : ReadAttribute("ac-current-divisor")
    {
    }

    ~ReadElectricalMeasurementAcCurrentDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000603) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcCurrentDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcCurrentDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcCurrentDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcCurrentDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcCurrentDivisor()
        : SubscribeAttribute("ac-current-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcCurrentDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000603) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcCurrentDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcCurrentDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcPowerMultiplier
 */
class ReadElectricalMeasurementAcPowerMultiplier : public ReadAttribute {
public:
    ReadElectricalMeasurementAcPowerMultiplier()
        : ReadAttribute("ac-power-multiplier")
    {
    }

    ~ReadElectricalMeasurementAcPowerMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000604) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcPowerMultiplierWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcPowerMultiplier response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcPowerMultiplier read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcPowerMultiplier : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcPowerMultiplier()
        : SubscribeAttribute("ac-power-multiplier")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcPowerMultiplier() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000604) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcPowerMultiplierWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcPowerMultiplier response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcPowerDivisor
 */
class ReadElectricalMeasurementAcPowerDivisor : public ReadAttribute {
public:
    ReadElectricalMeasurementAcPowerDivisor()
        : ReadAttribute("ac-power-divisor")
    {
    }

    ~ReadElectricalMeasurementAcPowerDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000605) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcPowerDivisorWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcPowerDivisor response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcPowerDivisor read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcPowerDivisor : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcPowerDivisor()
        : SubscribeAttribute("ac-power-divisor")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcPowerDivisor() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000605) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcPowerDivisorWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcPowerDivisor response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OverloadAlarmsMask
 */
class ReadElectricalMeasurementOverloadAlarmsMask : public ReadAttribute {
public:
    ReadElectricalMeasurementOverloadAlarmsMask()
        : ReadAttribute("overload-alarms-mask")
    {
    }

    ~ReadElectricalMeasurementOverloadAlarmsMask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000700) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeOverloadAlarmsMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.OverloadAlarmsMask response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement OverloadAlarmsMask read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementOverloadAlarmsMask : public WriteAttribute {
public:
    WriteElectricalMeasurementOverloadAlarmsMask()
        : WriteAttribute("overload-alarms-mask")
    {
        AddArgument("attr-name", "overload-alarms-mask");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementOverloadAlarmsMask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000700) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeOverloadAlarmsMaskWithValue:value
                                                    params:params
                                                completion:^(NSError * _Nullable error) {
                                                    if (error != nil) {
                                                        LogNSError("ElectricalMeasurement OverloadAlarmsMask write Error", error);
                                                    }
                                                    SetCommandExitStatus(error);
                                                }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeElectricalMeasurementOverloadAlarmsMask : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementOverloadAlarmsMask()
        : SubscribeAttribute("overload-alarms-mask")
    {
    }

    ~SubscribeAttributeElectricalMeasurementOverloadAlarmsMask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000700) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOverloadAlarmsMaskWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.OverloadAlarmsMask response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute VoltageOverload
 */
class ReadElectricalMeasurementVoltageOverload : public ReadAttribute {
public:
    ReadElectricalMeasurementVoltageOverload()
        : ReadAttribute("voltage-overload")
    {
    }

    ~ReadElectricalMeasurementVoltageOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000701) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeVoltageOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.VoltageOverload response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement VoltageOverload read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementVoltageOverload : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementVoltageOverload()
        : SubscribeAttribute("voltage-overload")
    {
    }

    ~SubscribeAttributeElectricalMeasurementVoltageOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000701) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVoltageOverloadWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.VoltageOverload response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CurrentOverload
 */
class ReadElectricalMeasurementCurrentOverload : public ReadAttribute {
public:
    ReadElectricalMeasurementCurrentOverload()
        : ReadAttribute("current-overload")
    {
    }

    ~ReadElectricalMeasurementCurrentOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000702) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeCurrentOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.CurrentOverload response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement CurrentOverload read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementCurrentOverload : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementCurrentOverload()
        : SubscribeAttribute("current-overload")
    {
    }

    ~SubscribeAttributeElectricalMeasurementCurrentOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000702) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCurrentOverloadWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.CurrentOverload response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcOverloadAlarmsMask
 */
class ReadElectricalMeasurementAcOverloadAlarmsMask : public ReadAttribute {
public:
    ReadElectricalMeasurementAcOverloadAlarmsMask()
        : ReadAttribute("ac-overload-alarms-mask")
    {
    }

    ~ReadElectricalMeasurementAcOverloadAlarmsMask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000800) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcOverloadAlarmsMaskWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcOverloadAlarmsMask response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcOverloadAlarmsMask read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteElectricalMeasurementAcOverloadAlarmsMask : public WriteAttribute {
public:
    WriteElectricalMeasurementAcOverloadAlarmsMask()
        : WriteAttribute("ac-overload-alarms-mask")
    {
        AddArgument("attr-name", "ac-overload-alarms-mask");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteElectricalMeasurementAcOverloadAlarmsMask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) WriteAttribute (0x00000800) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeAcOverloadAlarmsMaskWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("ElectricalMeasurement AcOverloadAlarmsMask write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeElectricalMeasurementAcOverloadAlarmsMask : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcOverloadAlarmsMask()
        : SubscribeAttribute("ac-overload-alarms-mask")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcOverloadAlarmsMask() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000800) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcOverloadAlarmsMaskWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcOverloadAlarmsMask response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcVoltageOverload
 */
class ReadElectricalMeasurementAcVoltageOverload : public ReadAttribute {
public:
    ReadElectricalMeasurementAcVoltageOverload()
        : ReadAttribute("ac-voltage-overload")
    {
    }

    ~ReadElectricalMeasurementAcVoltageOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000801) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcVoltageOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcVoltageOverload response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcVoltageOverload read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcVoltageOverload : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcVoltageOverload()
        : SubscribeAttribute("ac-voltage-overload")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcVoltageOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000801) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcVoltageOverloadWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcVoltageOverload response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcCurrentOverload
 */
class ReadElectricalMeasurementAcCurrentOverload : public ReadAttribute {
public:
    ReadElectricalMeasurementAcCurrentOverload()
        : ReadAttribute("ac-current-overload")
    {
    }

    ~ReadElectricalMeasurementAcCurrentOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000802) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcCurrentOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcCurrentOverload response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcCurrentOverload read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcCurrentOverload : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcCurrentOverload()
        : SubscribeAttribute("ac-current-overload")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcCurrentOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000802) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcCurrentOverloadWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcCurrentOverload response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcActivePowerOverload
 */
class ReadElectricalMeasurementAcActivePowerOverload : public ReadAttribute {
public:
    ReadElectricalMeasurementAcActivePowerOverload()
        : ReadAttribute("ac-active-power-overload")
    {
    }

    ~ReadElectricalMeasurementAcActivePowerOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000803) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcActivePowerOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcActivePowerOverload response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcActivePowerOverload read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcActivePowerOverload : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcActivePowerOverload()
        : SubscribeAttribute("ac-active-power-overload")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcActivePowerOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000803) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcActivePowerOverloadWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcActivePowerOverload response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcReactivePowerOverload
 */
class ReadElectricalMeasurementAcReactivePowerOverload : public ReadAttribute {
public:
    ReadElectricalMeasurementAcReactivePowerOverload()
        : ReadAttribute("ac-reactive-power-overload")
    {
    }

    ~ReadElectricalMeasurementAcReactivePowerOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000804) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcReactivePowerOverloadWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcReactivePowerOverload response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcReactivePowerOverload read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcReactivePowerOverload : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcReactivePowerOverload()
        : SubscribeAttribute("ac-reactive-power-overload")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcReactivePowerOverload() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000804) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcReactivePowerOverloadWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcReactivePowerOverload response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsOverVoltage
 */
class ReadElectricalMeasurementAverageRmsOverVoltage : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsOverVoltage()
        : ReadAttribute("average-rms-over-voltage")
    {
    }

    ~ReadElectricalMeasurementAverageRmsOverVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000805) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAverageRmsOverVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AverageRmsOverVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AverageRmsOverVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsOverVoltage : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsOverVoltage()
        : SubscribeAttribute("average-rms-over-voltage")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsOverVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000805) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsOverVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsOverVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsUnderVoltage
 */
class ReadElectricalMeasurementAverageRmsUnderVoltage : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsUnderVoltage()
        : ReadAttribute("average-rms-under-voltage")
    {
    }

    ~ReadElectricalMeasurementAverageRmsUnderVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000806) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAverageRmsUnderVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AverageRmsUnderVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltage : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltage()
        : SubscribeAttribute("average-rms-under-voltage")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000806) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsUnderVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeOverVoltage
 */
class ReadElectricalMeasurementRmsExtremeOverVoltage : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeOverVoltage()
        : ReadAttribute("rms-extreme-over-voltage")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeOverVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000807) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsExtremeOverVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsExtremeOverVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltage : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltage()
        : SubscribeAttribute("rms-extreme-over-voltage")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000807) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeOverVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeUnderVoltage
 */
class ReadElectricalMeasurementRmsExtremeUnderVoltage : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeUnderVoltage()
        : ReadAttribute("rms-extreme-under-voltage")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeUnderVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000808) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsExtremeUnderVoltageWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltage response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsExtremeUnderVoltage read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltage : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltage()
        : SubscribeAttribute("rms-extreme-under-voltage")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltage() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000808) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeUnderVoltageWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltage response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSag
 */
class ReadElectricalMeasurementRmsVoltageSag : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSag()
        : ReadAttribute("rms-voltage-sag")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSag() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000809) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSagWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSag response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSag read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSag : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSag()
        : SubscribeAttribute("rms-voltage-sag")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSag() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000809) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSagWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSag response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSwell
 */
class ReadElectricalMeasurementRmsVoltageSwell : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSwell()
        : ReadAttribute("rms-voltage-swell")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSwell() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000080A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSwellWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSwell response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSwell read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSwell : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSwell()
        : SubscribeAttribute("rms-voltage-swell")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSwell() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000080A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSwellWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSwell response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LineCurrentPhaseB
 */
class ReadElectricalMeasurementLineCurrentPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementLineCurrentPhaseB()
        : ReadAttribute("line-current-phase-b")
    {
    }

    ~ReadElectricalMeasurementLineCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000901) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeLineCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.LineCurrentPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement LineCurrentPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementLineCurrentPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementLineCurrentPhaseB()
        : SubscribeAttribute("line-current-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementLineCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000901) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLineCurrentPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.LineCurrentPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveCurrentPhaseB
 */
class ReadElectricalMeasurementActiveCurrentPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementActiveCurrentPhaseB()
        : ReadAttribute("active-current-phase-b")
    {
    }

    ~ReadElectricalMeasurementActiveCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000902) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActiveCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActiveCurrentPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActiveCurrentPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActiveCurrentPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActiveCurrentPhaseB()
        : SubscribeAttribute("active-current-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActiveCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000902) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveCurrentPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActiveCurrentPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ReactiveCurrentPhaseB
 */
class ReadElectricalMeasurementReactiveCurrentPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementReactiveCurrentPhaseB()
        : ReadAttribute("reactive-current-phase-b")
    {
    }

    ~ReadElectricalMeasurementReactiveCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000903) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeReactiveCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ReactiveCurrentPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ReactiveCurrentPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseB()
        : SubscribeAttribute("reactive-current-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000903) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReactiveCurrentPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ReactiveCurrentPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltagePhaseB
 */
class ReadElectricalMeasurementRmsVoltagePhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltagePhaseB()
        : ReadAttribute("rms-voltage-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsVoltagePhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000905) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltagePhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltagePhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltagePhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltagePhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltagePhaseB()
        : SubscribeAttribute("rms-voltage-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltagePhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000905) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltagePhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltagePhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageMinPhaseB
 */
class ReadElectricalMeasurementRmsVoltageMinPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageMinPhaseB()
        : ReadAttribute("rms-voltage-min-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageMinPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000906) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageMinPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageMinPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageMinPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseB()
        : SubscribeAttribute("rms-voltage-min-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000906) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageMinPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageMinPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageMaxPhaseB
 */
class ReadElectricalMeasurementRmsVoltageMaxPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageMaxPhaseB()
        : ReadAttribute("rms-voltage-max-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageMaxPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000907) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageMaxPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageMaxPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageMaxPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseB()
        : SubscribeAttribute("rms-voltage-max-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000907) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageMaxPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageMaxPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentPhaseB
 */
class ReadElectricalMeasurementRmsCurrentPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentPhaseB()
        : ReadAttribute("rms-current-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000908) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentPhaseB()
        : SubscribeAttribute("rms-current-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000908) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentMinPhaseB
 */
class ReadElectricalMeasurementRmsCurrentMinPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentMinPhaseB()
        : ReadAttribute("rms-current-min-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentMinPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000909) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentMinPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentMinPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentMinPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseB()
        : SubscribeAttribute("rms-current-min-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000909) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentMinPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentMinPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentMaxPhaseB
 */
class ReadElectricalMeasurementRmsCurrentMaxPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentMaxPhaseB()
        : ReadAttribute("rms-current-max-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentMaxPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000090A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentMaxPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentMaxPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentMaxPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseB()
        : SubscribeAttribute("rms-current-max-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000090A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentMaxPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentMaxPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerPhaseB
 */
class ReadElectricalMeasurementActivePowerPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerPhaseB()
        : ReadAttribute("active-power-phase-b")
    {
    }

    ~ReadElectricalMeasurementActivePowerPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000090B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerPhaseB()
        : SubscribeAttribute("active-power-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000090B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerMinPhaseB
 */
class ReadElectricalMeasurementActivePowerMinPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerMinPhaseB()
        : ReadAttribute("active-power-min-phase-b")
    {
    }

    ~ReadElectricalMeasurementActivePowerMinPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000090C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerMinPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerMinPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerMinPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerMinPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerMinPhaseB()
        : SubscribeAttribute("active-power-min-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerMinPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000090C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerMinPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerMinPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerMaxPhaseB
 */
class ReadElectricalMeasurementActivePowerMaxPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerMaxPhaseB()
        : ReadAttribute("active-power-max-phase-b")
    {
    }

    ~ReadElectricalMeasurementActivePowerMaxPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000090D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerMaxPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerMaxPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerMaxPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseB()
        : SubscribeAttribute("active-power-max-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000090D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerMaxPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerMaxPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ReactivePowerPhaseB
 */
class ReadElectricalMeasurementReactivePowerPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementReactivePowerPhaseB()
        : ReadAttribute("reactive-power-phase-b")
    {
    }

    ~ReadElectricalMeasurementReactivePowerPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000090E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeReactivePowerPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ReactivePowerPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ReactivePowerPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementReactivePowerPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementReactivePowerPhaseB()
        : SubscribeAttribute("reactive-power-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementReactivePowerPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000090E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReactivePowerPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ReactivePowerPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ApparentPowerPhaseB
 */
class ReadElectricalMeasurementApparentPowerPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementApparentPowerPhaseB()
        : ReadAttribute("apparent-power-phase-b")
    {
    }

    ~ReadElectricalMeasurementApparentPowerPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000090F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeApparentPowerPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ApparentPowerPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ApparentPowerPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementApparentPowerPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementApparentPowerPhaseB()
        : SubscribeAttribute("apparent-power-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementApparentPowerPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000090F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeApparentPowerPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ApparentPowerPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PowerFactorPhaseB
 */
class ReadElectricalMeasurementPowerFactorPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementPowerFactorPhaseB()
        : ReadAttribute("power-factor-phase-b")
    {
    }

    ~ReadElectricalMeasurementPowerFactorPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000910) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributePowerFactorPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.PowerFactorPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement PowerFactorPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementPowerFactorPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementPowerFactorPhaseB()
        : SubscribeAttribute("power-factor-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementPowerFactorPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000910) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePowerFactorPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.PowerFactorPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsVoltageMeasurementPeriodPhaseB
 */
class ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB()
        : ReadAttribute("average-rms-voltage-measurement-period-phase-b")
    {
    }

    ~ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000911) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AverageRmsVoltageMeasurementPeriodPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AverageRmsVoltageMeasurementPeriodPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB()
        : SubscribeAttribute("average-rms-voltage-measurement-period-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000911) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsVoltageMeasurementPeriodPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsOverVoltageCounterPhaseB
 */
class ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseB()
        : ReadAttribute("average-rms-over-voltage-counter-phase-b")
    {
    }

    ~ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000912) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeAverageRmsOverVoltageCounterPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsOverVoltageCounterPhaseB response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement AverageRmsOverVoltageCounterPhaseB read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseB()
        : SubscribeAttribute("average-rms-over-voltage-counter-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000912) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsOverVoltageCounterPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsOverVoltageCounterPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsUnderVoltageCounterPhaseB
 */
class ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB()
        : ReadAttribute("average-rms-under-voltage-counter-phase-b")
    {
    }

    ~ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000913) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAverageRmsUnderVoltageCounterPhaseBWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltageCounterPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AverageRmsUnderVoltageCounterPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB()
        : SubscribeAttribute("average-rms-under-voltage-counter-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000913) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsUnderVoltageCounterPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltageCounterPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeOverVoltagePeriodPhaseB
 */
class ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB()
        : ReadAttribute("rms-extreme-over-voltage-period-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000914) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeRmsExtremeOverVoltagePeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltagePeriodPhaseB response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement RmsExtremeOverVoltagePeriodPhaseB read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB()
        : SubscribeAttribute("rms-extreme-over-voltage-period-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000914) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeOverVoltagePeriodPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltagePeriodPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeUnderVoltagePeriodPhaseB
 */
class ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB()
        : ReadAttribute("rms-extreme-under-voltage-period-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000915) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltagePeriodPhaseB response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement RmsExtremeUnderVoltagePeriodPhaseB read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB()
        : SubscribeAttribute("rms-extreme-under-voltage-period-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000915) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltagePeriodPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSagPeriodPhaseB
 */
class ReadElectricalMeasurementRmsVoltageSagPeriodPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSagPeriodPhaseB()
        : ReadAttribute("rms-voltage-sag-period-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSagPeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000916) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSagPeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSagPeriodPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSagPeriodPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseB()
        : SubscribeAttribute("rms-voltage-sag-period-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000916) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSagPeriodPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSagPeriodPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSwellPeriodPhaseB
 */
class ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseB : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseB()
        : ReadAttribute("rms-voltage-swell-period-phase-b")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000917) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSwellPeriodPhaseBWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSwellPeriodPhaseB response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSwellPeriodPhaseB read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseB : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseB()
        : SubscribeAttribute("rms-voltage-swell-period-phase-b")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseB() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000917) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSwellPeriodPhaseBWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSwellPeriodPhaseB response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LineCurrentPhaseC
 */
class ReadElectricalMeasurementLineCurrentPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementLineCurrentPhaseC()
        : ReadAttribute("line-current-phase-c")
    {
    }

    ~ReadElectricalMeasurementLineCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A01) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeLineCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.LineCurrentPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement LineCurrentPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementLineCurrentPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementLineCurrentPhaseC()
        : SubscribeAttribute("line-current-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementLineCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A01) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLineCurrentPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.LineCurrentPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActiveCurrentPhaseC
 */
class ReadElectricalMeasurementActiveCurrentPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementActiveCurrentPhaseC()
        : ReadAttribute("active-current-phase-c")
    {
    }

    ~ReadElectricalMeasurementActiveCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A02) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActiveCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActiveCurrentPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActiveCurrentPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActiveCurrentPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActiveCurrentPhaseC()
        : SubscribeAttribute("active-current-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActiveCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A02) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActiveCurrentPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActiveCurrentPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ReactiveCurrentPhaseC
 */
class ReadElectricalMeasurementReactiveCurrentPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementReactiveCurrentPhaseC()
        : ReadAttribute("reactive-current-phase-c")
    {
    }

    ~ReadElectricalMeasurementReactiveCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A03) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeReactiveCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ReactiveCurrentPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ReactiveCurrentPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseC()
        : SubscribeAttribute("reactive-current-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A03) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReactiveCurrentPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ReactiveCurrentPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltagePhaseC
 */
class ReadElectricalMeasurementRmsVoltagePhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltagePhaseC()
        : ReadAttribute("rms-voltage-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsVoltagePhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A05) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltagePhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltagePhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltagePhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltagePhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltagePhaseC()
        : SubscribeAttribute("rms-voltage-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltagePhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A05) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltagePhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltagePhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageMinPhaseC
 */
class ReadElectricalMeasurementRmsVoltageMinPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageMinPhaseC()
        : ReadAttribute("rms-voltage-min-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageMinPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A06) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageMinPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageMinPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageMinPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseC()
        : SubscribeAttribute("rms-voltage-min-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A06) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageMinPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageMinPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageMaxPhaseC
 */
class ReadElectricalMeasurementRmsVoltageMaxPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageMaxPhaseC()
        : ReadAttribute("rms-voltage-max-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageMaxPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A07) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageMaxPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageMaxPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageMaxPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseC()
        : SubscribeAttribute("rms-voltage-max-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A07) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageMaxPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageMaxPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentPhaseC
 */
class ReadElectricalMeasurementRmsCurrentPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentPhaseC()
        : ReadAttribute("rms-current-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A08) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentPhaseC()
        : SubscribeAttribute("rms-current-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A08) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentMinPhaseC
 */
class ReadElectricalMeasurementRmsCurrentMinPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentMinPhaseC()
        : ReadAttribute("rms-current-min-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentMinPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A09) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentMinPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentMinPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentMinPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseC()
        : SubscribeAttribute("rms-current-min-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A09) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentMinPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentMinPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsCurrentMaxPhaseC
 */
class ReadElectricalMeasurementRmsCurrentMaxPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsCurrentMaxPhaseC()
        : ReadAttribute("rms-current-max-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsCurrentMaxPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A0A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsCurrentMaxPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsCurrentMaxPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsCurrentMaxPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseC()
        : SubscribeAttribute("rms-current-max-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A0A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsCurrentMaxPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsCurrentMaxPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerPhaseC
 */
class ReadElectricalMeasurementActivePowerPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerPhaseC()
        : ReadAttribute("active-power-phase-c")
    {
    }

    ~ReadElectricalMeasurementActivePowerPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A0B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerPhaseC()
        : SubscribeAttribute("active-power-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A0B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerMinPhaseC
 */
class ReadElectricalMeasurementActivePowerMinPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerMinPhaseC()
        : ReadAttribute("active-power-min-phase-c")
    {
    }

    ~ReadElectricalMeasurementActivePowerMinPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A0C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerMinPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerMinPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerMinPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerMinPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerMinPhaseC()
        : SubscribeAttribute("active-power-min-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerMinPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A0C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerMinPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerMinPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ActivePowerMaxPhaseC
 */
class ReadElectricalMeasurementActivePowerMaxPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementActivePowerMaxPhaseC()
        : ReadAttribute("active-power-max-phase-c")
    {
    }

    ~ReadElectricalMeasurementActivePowerMaxPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A0D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeActivePowerMaxPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ActivePowerMaxPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ActivePowerMaxPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseC()
        : SubscribeAttribute("active-power-max-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A0D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeActivePowerMaxPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ActivePowerMaxPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ReactivePowerPhaseC
 */
class ReadElectricalMeasurementReactivePowerPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementReactivePowerPhaseC()
        : ReadAttribute("reactive-power-phase-c")
    {
    }

    ~ReadElectricalMeasurementReactivePowerPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A0E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeReactivePowerPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ReactivePowerPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ReactivePowerPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementReactivePowerPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementReactivePowerPhaseC()
        : SubscribeAttribute("reactive-power-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementReactivePowerPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A0E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeReactivePowerPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ReactivePowerPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ApparentPowerPhaseC
 */
class ReadElectricalMeasurementApparentPowerPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementApparentPowerPhaseC()
        : ReadAttribute("apparent-power-phase-c")
    {
    }

    ~ReadElectricalMeasurementApparentPowerPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A0F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeApparentPowerPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ApparentPowerPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ApparentPowerPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementApparentPowerPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementApparentPowerPhaseC()
        : SubscribeAttribute("apparent-power-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementApparentPowerPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A0F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeApparentPowerPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ApparentPowerPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute PowerFactorPhaseC
 */
class ReadElectricalMeasurementPowerFactorPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementPowerFactorPhaseC()
        : ReadAttribute("power-factor-phase-c")
    {
    }

    ~ReadElectricalMeasurementPowerFactorPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A10) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributePowerFactorPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.PowerFactorPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement PowerFactorPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementPowerFactorPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementPowerFactorPhaseC()
        : SubscribeAttribute("power-factor-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementPowerFactorPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A10) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributePowerFactorPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.PowerFactorPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsVoltageMeasurementPeriodPhaseC
 */
class ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC()
        : ReadAttribute("average-rms-voltage-measurement-period-phase-c")
    {
    }

    ~ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A11) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AverageRmsVoltageMeasurementPeriodPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AverageRmsVoltageMeasurementPeriodPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC()
        : SubscribeAttribute("average-rms-voltage-measurement-period-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A11) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsVoltageMeasurementPeriodPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsOverVoltageCounterPhaseC
 */
class ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseC()
        : ReadAttribute("average-rms-over-voltage-counter-phase-c")
    {
    }

    ~ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A12) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeAverageRmsOverVoltageCounterPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsOverVoltageCounterPhaseC response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement AverageRmsOverVoltageCounterPhaseC read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseC()
        : SubscribeAttribute("average-rms-over-voltage-counter-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A12) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsOverVoltageCounterPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsOverVoltageCounterPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AverageRmsUnderVoltageCounterPhaseC
 */
class ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC()
        : ReadAttribute("average-rms-under-voltage-counter-phase-c")
    {
    }

    ~ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A13) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAverageRmsUnderVoltageCounterPhaseCWithCompletion:^(
            NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltageCounterPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AverageRmsUnderVoltageCounterPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC()
        : SubscribeAttribute("average-rms-under-voltage-counter-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A13) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAverageRmsUnderVoltageCounterPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AverageRmsUnderVoltageCounterPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeOverVoltagePeriodPhaseC
 */
class ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC()
        : ReadAttribute("rms-extreme-over-voltage-period-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A14) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeRmsExtremeOverVoltagePeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltagePeriodPhaseC response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement RmsExtremeOverVoltagePeriodPhaseC read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC()
        : SubscribeAttribute("rms-extreme-over-voltage-period-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A14) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeOverVoltagePeriodPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeOverVoltagePeriodPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsExtremeUnderVoltagePeriodPhaseC
 */
class ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC()
        : ReadAttribute("rms-extreme-under-voltage-period-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A15) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster
            readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltagePeriodPhaseC response %@", [value description]);
                if (error != nil) {
                    LogNSError("ElectricalMeasurement RmsExtremeUnderVoltagePeriodPhaseC read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC()
        : SubscribeAttribute("rms-extreme-under-voltage-period-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A15) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsExtremeUnderVoltagePeriodPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSagPeriodPhaseC
 */
class ReadElectricalMeasurementRmsVoltageSagPeriodPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSagPeriodPhaseC()
        : ReadAttribute("rms-voltage-sag-period-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSagPeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A16) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSagPeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSagPeriodPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSagPeriodPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseC()
        : SubscribeAttribute("rms-voltage-sag-period-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A16) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSagPeriodPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSagPeriodPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RmsVoltageSwellPeriodPhaseC
 */
class ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseC : public ReadAttribute {
public:
    ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseC()
        : ReadAttribute("rms-voltage-swell-period-phase-c")
    {
    }

    ~ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x00000A17) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeRmsVoltageSwellPeriodPhaseCWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.RmsVoltageSwellPeriodPhaseC response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement RmsVoltageSwellPeriodPhaseC read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseC : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseC()
        : SubscribeAttribute("rms-voltage-swell-period-phase-c")
    {
    }

    ~SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseC() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x00000A17) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRmsVoltageSwellPeriodPhaseCWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.RmsVoltageSwellPeriodPhaseC response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadElectricalMeasurementGeneratedCommandList : public ReadAttribute {
public:
    ReadElectricalMeasurementGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadElectricalMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeElectricalMeasurementGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadElectricalMeasurementAcceptedCommandList : public ReadAttribute {
public:
    ReadElectricalMeasurementAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadElectricalMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadElectricalMeasurementAttributeList : public ReadAttribute {
public:
    ReadElectricalMeasurementAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadElectricalMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeElectricalMeasurementAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadElectricalMeasurementFeatureMap : public ReadAttribute {
public:
    ReadElectricalMeasurementFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadElectricalMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeElectricalMeasurementFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadElectricalMeasurementClusterRevision : public ReadAttribute {
public:
    ReadElectricalMeasurementClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadElectricalMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeElectricalMeasurementClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterElectricalMeasurement alloc] initWithDevice:device
                                                                                 endpointID:@(endpointId)
                                                                                      queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster UnitTesting                                                 | 0xFFF1FC05|
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * Test                                                              |   0x00 |
| * TestNotHandled                                                    |   0x01 |
| * TestSpecific                                                      |   0x02 |
| * TestUnknownCommand                                                |   0x03 |
| * TestAddArguments                                                  |   0x04 |
| * TestSimpleArgumentRequest                                         |   0x05 |
| * TestStructArrayArgumentRequest                                    |   0x06 |
| * TestStructArgumentRequest                                         |   0x07 |
| * TestNestedStructArgumentRequest                                   |   0x08 |
| * TestListStructArgumentRequest                                     |   0x09 |
| * TestListInt8UArgumentRequest                                      |   0x0A |
| * TestNestedStructListArgumentRequest                               |   0x0B |
| * TestListNestedStructListArgumentRequest                           |   0x0C |
| * TestListInt8UReverseRequest                                       |   0x0D |
| * TestEnumsRequest                                                  |   0x0E |
| * TestNullableOptionalRequest                                       |   0x0F |
| * TestComplexNullableOptionalRequest                                |   0x10 |
| * SimpleStructEchoRequest                                           |   0x11 |
| * TimedInvokeRequest                                                |   0x12 |
| * TestSimpleOptionalArgumentRequest                                 |   0x13 |
| * TestEmitTestEventRequest                                          |   0x14 |
| * TestEmitTestFabricScopedEventRequest                              |   0x15 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * Boolean                                                           | 0x0000 |
| * Bitmap8                                                           | 0x0001 |
| * Bitmap16                                                          | 0x0002 |
| * Bitmap32                                                          | 0x0003 |
| * Bitmap64                                                          | 0x0004 |
| * Int8u                                                             | 0x0005 |
| * Int16u                                                            | 0x0006 |
| * Int24u                                                            | 0x0007 |
| * Int32u                                                            | 0x0008 |
| * Int40u                                                            | 0x0009 |
| * Int48u                                                            | 0x000A |
| * Int56u                                                            | 0x000B |
| * Int64u                                                            | 0x000C |
| * Int8s                                                             | 0x000D |
| * Int16s                                                            | 0x000E |
| * Int24s                                                            | 0x000F |
| * Int32s                                                            | 0x0010 |
| * Int40s                                                            | 0x0011 |
| * Int48s                                                            | 0x0012 |
| * Int56s                                                            | 0x0013 |
| * Int64s                                                            | 0x0014 |
| * Enum8                                                             | 0x0015 |
| * Enum16                                                            | 0x0016 |
| * FloatSingle                                                       | 0x0017 |
| * FloatDouble                                                       | 0x0018 |
| * OctetString                                                       | 0x0019 |
| * ListInt8u                                                         | 0x001A |
| * ListOctetString                                                   | 0x001B |
| * ListStructOctetString                                             | 0x001C |
| * LongOctetString                                                   | 0x001D |
| * CharString                                                        | 0x001E |
| * LongCharString                                                    | 0x001F |
| * EpochUs                                                           | 0x0020 |
| * EpochS                                                            | 0x0021 |
| * VendorId                                                          | 0x0022 |
| * ListNullablesAndOptionalsStruct                                   | 0x0023 |
| * EnumAttr                                                          | 0x0024 |
| * StructAttr                                                        | 0x0025 |
| * RangeRestrictedInt8u                                              | 0x0026 |
| * RangeRestrictedInt8s                                              | 0x0027 |
| * RangeRestrictedInt16u                                             | 0x0028 |
| * RangeRestrictedInt16s                                             | 0x0029 |
| * ListLongOctetString                                               | 0x002A |
| * ListFabricScoped                                                  | 0x002B |
| * TimedWriteBoolean                                                 | 0x0030 |
| * GeneralErrorBoolean                                               | 0x0031 |
| * ClusterErrorBoolean                                               | 0x0032 |
| * Unsupported                                                       | 0x00FF |
| * NullableBoolean                                                   | 0x4000 |
| * NullableBitmap8                                                   | 0x4001 |
| * NullableBitmap16                                                  | 0x4002 |
| * NullableBitmap32                                                  | 0x4003 |
| * NullableBitmap64                                                  | 0x4004 |
| * NullableInt8u                                                     | 0x4005 |
| * NullableInt16u                                                    | 0x4006 |
| * NullableInt24u                                                    | 0x4007 |
| * NullableInt32u                                                    | 0x4008 |
| * NullableInt40u                                                    | 0x4009 |
| * NullableInt48u                                                    | 0x400A |
| * NullableInt56u                                                    | 0x400B |
| * NullableInt64u                                                    | 0x400C |
| * NullableInt8s                                                     | 0x400D |
| * NullableInt16s                                                    | 0x400E |
| * NullableInt24s                                                    | 0x400F |
| * NullableInt32s                                                    | 0x4010 |
| * NullableInt40s                                                    | 0x4011 |
| * NullableInt48s                                                    | 0x4012 |
| * NullableInt56s                                                    | 0x4013 |
| * NullableInt64s                                                    | 0x4014 |
| * NullableEnum8                                                     | 0x4015 |
| * NullableEnum16                                                    | 0x4016 |
| * NullableFloatSingle                                               | 0x4017 |
| * NullableFloatDouble                                               | 0x4018 |
| * NullableOctetString                                               | 0x4019 |
| * NullableCharString                                                | 0x401E |
| * NullableEnumAttr                                                  | 0x4024 |
| * NullableStruct                                                    | 0x4025 |
| * NullableRangeRestrictedInt8u                                      | 0x4026 |
| * NullableRangeRestrictedInt8s                                      | 0x4027 |
| * NullableRangeRestrictedInt16u                                     | 0x4028 |
| * NullableRangeRestrictedInt16s                                     | 0x4029 |
| * WriteOnlyInt8u                                                    | 0x402A |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * TestEvent                                                         | 0x0001 |
| * TestFabricScopedEvent                                             | 0x0002 |
\*----------------------------------------------------------------------------*/

/*
 * Command Test
 */
class UnitTestingTest : public ClusterCommand {
public:
    UnitTestingTest()
        : ClusterCommand("test")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testWithParams:params
                         completion:^(NSError * _Nullable error) {
                             responsesNeeded--;
                             if (error != nil) {
                                 mError = error;
                                 LogNSError("Error", error);
                             }
                             if (responsesNeeded == 0) {
                                 SetCommandExitStatus(mError);
                             }
                         }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command TestNotHandled
 */
class UnitTestingTestNotHandled : public ClusterCommand {
public:
    UnitTestingTestNotHandled()
        : ClusterCommand("test-not-handled")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestNotHandledParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testNotHandledWithParams:params
                                   completion:^(NSError * _Nullable error) {
                                       responsesNeeded--;
                                       if (error != nil) {
                                           mError = error;
                                           LogNSError("Error", error);
                                       }
                                       if (responsesNeeded == 0) {
                                           SetCommandExitStatus(mError);
                                       }
                                   }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command TestSpecific
 */
class UnitTestingTestSpecific : public ClusterCommand {
public:
    UnitTestingTestSpecific()
        : ClusterCommand("test-specific")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestSpecificParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testSpecificWithParams:params
                                 completion:^(MTRUnitTestingClusterTestSpecificResponseParams * _Nullable values,
                                     NSError * _Nullable error) {
                                     NSLog(@"Values: %@", values);
                                     responsesNeeded--;
                                     if (error != nil) {
                                         mError = error;
                                         LogNSError("Error", error);
                                     }
                                     if (responsesNeeded == 0) {
                                         SetCommandExitStatus(mError);
                                     }
                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command TestUnknownCommand
 */
class UnitTestingTestUnknownCommand : public ClusterCommand {
public:
    UnitTestingTestUnknownCommand()
        : ClusterCommand("test-unknown-command")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestUnknownCommandParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testUnknownCommandWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command TestAddArguments
 */
class UnitTestingTestAddArguments : public ClusterCommand {
public:
    UnitTestingTestAddArguments()
        : ClusterCommand("test-add-arguments")
    {
        AddArgument("Arg1", 0, UINT8_MAX, &mRequest.arg1);
        AddArgument("Arg2", 0, UINT8_MAX, &mRequest.arg2);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestAddArgumentsParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [NSNumber numberWithUnsignedChar:mRequest.arg1];
        params.arg2 = [NSNumber numberWithUnsignedChar:mRequest.arg2];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testAddArgumentsWithParams:params
                                     completion:^(MTRUnitTestingClusterTestAddArgumentsResponseParams * _Nullable values,
                                         NSError * _Nullable error) {
                                         NSLog(@"Values: %@", values);
                                         responsesNeeded--;
                                         if (error != nil) {
                                             mError = error;
                                             LogNSError("Error", error);
                                         }
                                         if (responsesNeeded == 0) {
                                             SetCommandExitStatus(mError);
                                         }
                                     }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestAddArguments::Type mRequest;
};

/*
 * Command TestSimpleArgumentRequest
 */
class UnitTestingTestSimpleArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestSimpleArgumentRequest()
        : ClusterCommand("test-simple-argument-request")
    {
        AddArgument("Arg1", 0, 1, &mRequest.arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestSimpleArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [NSNumber numberWithBool:mRequest.arg1];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testSimpleArgumentRequestWithParams:params
                                              completion:^(MTRUnitTestingClusterTestSimpleArgumentResponseParams * _Nullable values,
                                                  NSError * _Nullable error) {
                                                  NSLog(@"Values: %@", values);
                                                  responsesNeeded--;
                                                  if (error != nil) {
                                                      mError = error;
                                                      LogNSError("Error", error);
                                                  }
                                                  if (responsesNeeded == 0) {
                                                      SetCommandExitStatus(mError);
                                                  }
                                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestSimpleArgumentRequest::Type mRequest;
};

/*
 * Command TestStructArrayArgumentRequest
 */
class UnitTestingTestStructArrayArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestStructArrayArgumentRequest()
        : ClusterCommand("test-struct-array-argument-request")
        , mComplex_Arg1(&mRequest.arg1)
        , mComplex_Arg2(&mRequest.arg2)
        , mComplex_Arg3(&mRequest.arg3)
        , mComplex_Arg4(&mRequest.arg4)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        AddArgument("Arg2", &mComplex_Arg2);
        AddArgument("Arg3", &mComplex_Arg3);
        AddArgument("Arg4", &mComplex_Arg4);
        AddArgument("Arg5", 0, UINT8_MAX, &mRequest.arg5);
        AddArgument("Arg6", 0, 1, &mRequest.arg6);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestStructArrayArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg1) {
                MTRUnitTestingClusterNestedStructList * newElement_0;
                newElement_0 = [MTRUnitTestingClusterNestedStructList new];
                newElement_0.a = [NSNumber numberWithUnsignedChar:entry_0.a];
                newElement_0.b = [NSNumber numberWithBool:entry_0.b];
                newElement_0.c = [MTRUnitTestingClusterSimpleStruct new];
                newElement_0.c.a = [NSNumber numberWithUnsignedChar:entry_0.c.a];
                newElement_0.c.b = [NSNumber numberWithBool:entry_0.c.b];
                newElement_0.c.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.c)];
                newElement_0.c.d = [NSData dataWithBytes:entry_0.c.d.data() length:entry_0.c.d.size()];
                newElement_0.c.e = [[NSString alloc] initWithBytes:entry_0.c.e.data()
                                                            length:entry_0.c.e.size()
                                                          encoding:NSUTF8StringEncoding];
                newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()];
                newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g];
                newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h];
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.d) {
                        MTRUnitTestingClusterSimpleStruct * newElement_2;
                        newElement_2 = [MTRUnitTestingClusterSimpleStruct new];
                        newElement_2.a = [NSNumber numberWithUnsignedChar:entry_2.a];
                        newElement_2.b = [NSNumber numberWithBool:entry_2.b];
                        newElement_2.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.c)];
                        newElement_2.d = [NSData dataWithBytes:entry_2.d.data() length:entry_2.d.size()];
                        newElement_2.e = [[NSString alloc] initWithBytes:entry_2.e.data()
                                                                  length:entry_2.e.size()
                                                                encoding:NSUTF8StringEncoding];
                        newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()];
                        newElement_2.g = [NSNumber numberWithFloat:entry_2.g];
                        newElement_2.h = [NSNumber numberWithDouble:entry_2.h];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.d = array_2;
                }
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.e) {
                        NSNumber * newElement_2;
                        newElement_2 = [NSNumber numberWithUnsignedInt:entry_2];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.e = array_2;
                }
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.f) {
                        NSData * newElement_2;
                        newElement_2 = [NSData dataWithBytes:entry_2.data() length:entry_2.size()];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.f = array_2;
                }
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.g) {
                        NSNumber * newElement_2;
                        newElement_2 = [NSNumber numberWithUnsignedChar:entry_2];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.g = array_2;
                }
                [array_0 addObject:newElement_0];
            }
            params.arg1 = array_0;
        }
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg2) {
                MTRUnitTestingClusterSimpleStruct * newElement_0;
                newElement_0 = [MTRUnitTestingClusterSimpleStruct new];
                newElement_0.a = [NSNumber numberWithUnsignedChar:entry_0.a];
                newElement_0.b = [NSNumber numberWithBool:entry_0.b];
                newElement_0.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c)];
                newElement_0.d = [NSData dataWithBytes:entry_0.d.data() length:entry_0.d.size()];
                newElement_0.e = [[NSString alloc] initWithBytes:entry_0.e.data()
                                                          length:entry_0.e.size()
                                                        encoding:NSUTF8StringEncoding];
                newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()];
                newElement_0.g = [NSNumber numberWithFloat:entry_0.g];
                newElement_0.h = [NSNumber numberWithDouble:entry_0.h];
                [array_0 addObject:newElement_0];
            }
            params.arg2 = array_0;
        }
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg3) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0)];
                [array_0 addObject:newElement_0];
            }
            params.arg3 = array_0;
        }
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg4) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithBool:entry_0];
                [array_0 addObject:newElement_0];
            }
            params.arg4 = array_0;
        }
        params.arg5 = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg5)];
        params.arg6 = [NSNumber numberWithBool:mRequest.arg6];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                testStructArrayArgumentRequestWithParams:params
                                              completion:^(
                                                  MTRUnitTestingClusterTestStructArrayArgumentResponseParams * _Nullable values,
                                                  NSError * _Nullable error) {
                                                  NSLog(@"Values: %@", values);
                                                  responsesNeeded--;
                                                  if (error != nil) {
                                                      mError = error;
                                                      LogNSError("Error", error);
                                                  }
                                                  if (responsesNeeded == 0) {
                                                      SetCommandExitStatus(mError);
                                                  }
                                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestStructArrayArgumentRequest::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::NestedStructList::Type>>
        mComplex_Arg1;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type>>
        mComplex_Arg2;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::SimpleEnum>> mComplex_Arg3;
    TypedComplexArgument<chip::app::DataModel::List<const bool>> mComplex_Arg4;
};

/*
 * Command TestStructArgumentRequest
 */
class UnitTestingTestStructArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestStructArgumentRequest()
        : ClusterCommand("test-struct-argument-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestStructArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [MTRUnitTestingClusterSimpleStruct new];
        params.arg1.a = [NSNumber numberWithUnsignedChar:mRequest.arg1.a];
        params.arg1.b = [NSNumber numberWithBool:mRequest.arg1.b];
        params.arg1.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c)];
        params.arg1.d = [NSData dataWithBytes:mRequest.arg1.d.data() length:mRequest.arg1.d.size()];
        params.arg1.e = [[NSString alloc] initWithBytes:mRequest.arg1.e.data()
                                                 length:mRequest.arg1.e.size()
                                               encoding:NSUTF8StringEncoding];
        params.arg1.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.f.Raw()];
        params.arg1.g = [NSNumber numberWithFloat:mRequest.arg1.g];
        params.arg1.h = [NSNumber numberWithDouble:mRequest.arg1.h];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testStructArgumentRequestWithParams:params
                                              completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable values,
                                                  NSError * _Nullable error) {
                                                  NSLog(@"Values: %@", values);
                                                  responsesNeeded--;
                                                  if (error != nil) {
                                                      mError = error;
                                                      LogNSError("Error", error);
                                                  }
                                                  if (responsesNeeded == 0) {
                                                      SetCommandExitStatus(mError);
                                                  }
                                              }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestStructArgumentRequest::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type> mComplex_Arg1;
};

/*
 * Command TestNestedStructArgumentRequest
 */
class UnitTestingTestNestedStructArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestNestedStructArgumentRequest()
        : ClusterCommand("test-nested-struct-argument-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestNestedStructArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [MTRUnitTestingClusterNestedStruct new];
        params.arg1.a = [NSNumber numberWithUnsignedChar:mRequest.arg1.a];
        params.arg1.b = [NSNumber numberWithBool:mRequest.arg1.b];
        params.arg1.c = [MTRUnitTestingClusterSimpleStruct new];
        params.arg1.c.a = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.a];
        params.arg1.c.b = [NSNumber numberWithBool:mRequest.arg1.c.b];
        params.arg1.c.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c.c)];
        params.arg1.c.d = [NSData dataWithBytes:mRequest.arg1.c.d.data() length:mRequest.arg1.c.d.size()];
        params.arg1.c.e = [[NSString alloc] initWithBytes:mRequest.arg1.c.e.data()
                                                   length:mRequest.arg1.c.e.size()
                                                 encoding:NSUTF8StringEncoding];
        params.arg1.c.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.f.Raw()];
        params.arg1.c.g = [NSNumber numberWithFloat:mRequest.arg1.c.g];
        params.arg1.c.h = [NSNumber numberWithDouble:mRequest.arg1.c.h];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testNestedStructArgumentRequestWithParams:params
                                                    completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable values,
                                                        NSError * _Nullable error) {
                                                        NSLog(@"Values: %@", values);
                                                        responsesNeeded--;
                                                        if (error != nil) {
                                                            mError = error;
                                                            LogNSError("Error", error);
                                                        }
                                                        if (responsesNeeded == 0) {
                                                            SetCommandExitStatus(mError);
                                                        }
                                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestNestedStructArgumentRequest::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::UnitTesting::Structs::NestedStruct::Type> mComplex_Arg1;
};

/*
 * Command TestListStructArgumentRequest
 */
class UnitTestingTestListStructArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestListStructArgumentRequest()
        : ClusterCommand("test-list-struct-argument-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestListStructArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg1) {
                MTRUnitTestingClusterSimpleStruct * newElement_0;
                newElement_0 = [MTRUnitTestingClusterSimpleStruct new];
                newElement_0.a = [NSNumber numberWithUnsignedChar:entry_0.a];
                newElement_0.b = [NSNumber numberWithBool:entry_0.b];
                newElement_0.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c)];
                newElement_0.d = [NSData dataWithBytes:entry_0.d.data() length:entry_0.d.size()];
                newElement_0.e = [[NSString alloc] initWithBytes:entry_0.e.data()
                                                          length:entry_0.e.size()
                                                        encoding:NSUTF8StringEncoding];
                newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()];
                newElement_0.g = [NSNumber numberWithFloat:entry_0.g];
                newElement_0.h = [NSNumber numberWithDouble:entry_0.h];
                [array_0 addObject:newElement_0];
            }
            params.arg1 = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testListStructArgumentRequestWithParams:params
                                                  completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable values,
                                                      NSError * _Nullable error) {
                                                      NSLog(@"Values: %@", values);
                                                      responsesNeeded--;
                                                      if (error != nil) {
                                                          mError = error;
                                                          LogNSError("Error", error);
                                                      }
                                                      if (responsesNeeded == 0) {
                                                          SetCommandExitStatus(mError);
                                                      }
                                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestListStructArgumentRequest::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type>>
        mComplex_Arg1;
};

/*
 * Command TestListInt8UArgumentRequest
 */
class UnitTestingTestListInt8UArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestListInt8UArgumentRequest()
        : ClusterCommand("test-list-int8uargument-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestListInt8UArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg1) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithUnsignedChar:entry_0];
                [array_0 addObject:newElement_0];
            }
            params.arg1 = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testListInt8UArgumentRequestWithParams:params
                                                 completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable values,
                                                     NSError * _Nullable error) {
                                                     NSLog(@"Values: %@", values);
                                                     responsesNeeded--;
                                                     if (error != nil) {
                                                         mError = error;
                                                         LogNSError("Error", error);
                                                     }
                                                     if (responsesNeeded == 0) {
                                                         SetCommandExitStatus(mError);
                                                     }
                                                 }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestListInt8UArgumentRequest::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const uint8_t>> mComplex_Arg1;
};

/*
 * Command TestNestedStructListArgumentRequest
 */
class UnitTestingTestNestedStructListArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestNestedStructListArgumentRequest()
        : ClusterCommand("test-nested-struct-list-argument-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestNestedStructListArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [MTRUnitTestingClusterNestedStructList new];
        params.arg1.a = [NSNumber numberWithUnsignedChar:mRequest.arg1.a];
        params.arg1.b = [NSNumber numberWithBool:mRequest.arg1.b];
        params.arg1.c = [MTRUnitTestingClusterSimpleStruct new];
        params.arg1.c.a = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.a];
        params.arg1.c.b = [NSNumber numberWithBool:mRequest.arg1.c.b];
        params.arg1.c.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c.c)];
        params.arg1.c.d = [NSData dataWithBytes:mRequest.arg1.c.d.data() length:mRequest.arg1.c.d.size()];
        params.arg1.c.e = [[NSString alloc] initWithBytes:mRequest.arg1.c.e.data()
                                                   length:mRequest.arg1.c.e.size()
                                                 encoding:NSUTF8StringEncoding];
        params.arg1.c.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.f.Raw()];
        params.arg1.c.g = [NSNumber numberWithFloat:mRequest.arg1.c.g];
        params.arg1.c.h = [NSNumber numberWithDouble:mRequest.arg1.c.h];
        { // Scope for our temporary variables
            auto * array_1 = [NSMutableArray new];
            for (auto & entry_1 : mRequest.arg1.d) {
                MTRUnitTestingClusterSimpleStruct * newElement_1;
                newElement_1 = [MTRUnitTestingClusterSimpleStruct new];
                newElement_1.a = [NSNumber numberWithUnsignedChar:entry_1.a];
                newElement_1.b = [NSNumber numberWithBool:entry_1.b];
                newElement_1.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1.c)];
                newElement_1.d = [NSData dataWithBytes:entry_1.d.data() length:entry_1.d.size()];
                newElement_1.e = [[NSString alloc] initWithBytes:entry_1.e.data()
                                                          length:entry_1.e.size()
                                                        encoding:NSUTF8StringEncoding];
                newElement_1.f = [NSNumber numberWithUnsignedChar:entry_1.f.Raw()];
                newElement_1.g = [NSNumber numberWithFloat:entry_1.g];
                newElement_1.h = [NSNumber numberWithDouble:entry_1.h];
                [array_1 addObject:newElement_1];
            }
            params.arg1.d = array_1;
        }
        { // Scope for our temporary variables
            auto * array_1 = [NSMutableArray new];
            for (auto & entry_1 : mRequest.arg1.e) {
                NSNumber * newElement_1;
                newElement_1 = [NSNumber numberWithUnsignedInt:entry_1];
                [array_1 addObject:newElement_1];
            }
            params.arg1.e = array_1;
        }
        { // Scope for our temporary variables
            auto * array_1 = [NSMutableArray new];
            for (auto & entry_1 : mRequest.arg1.f) {
                NSData * newElement_1;
                newElement_1 = [NSData dataWithBytes:entry_1.data() length:entry_1.size()];
                [array_1 addObject:newElement_1];
            }
            params.arg1.f = array_1;
        }
        { // Scope for our temporary variables
            auto * array_1 = [NSMutableArray new];
            for (auto & entry_1 : mRequest.arg1.g) {
                NSNumber * newElement_1;
                newElement_1 = [NSNumber numberWithUnsignedChar:entry_1];
                [array_1 addObject:newElement_1];
            }
            params.arg1.g = array_1;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testNestedStructListArgumentRequestWithParams:params
                                                        completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable values,
                                                            NSError * _Nullable error) {
                                                            NSLog(@"Values: %@", values);
                                                            responsesNeeded--;
                                                            if (error != nil) {
                                                                mError = error;
                                                                LogNSError("Error", error);
                                                            }
                                                            if (responsesNeeded == 0) {
                                                                SetCommandExitStatus(mError);
                                                            }
                                                        }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestNestedStructListArgumentRequest::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::UnitTesting::Structs::NestedStructList::Type> mComplex_Arg1;
};

/*
 * Command TestListNestedStructListArgumentRequest
 */
class UnitTestingTestListNestedStructListArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestListNestedStructListArgumentRequest()
        : ClusterCommand("test-list-nested-struct-list-argument-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestListNestedStructListArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg1) {
                MTRUnitTestingClusterNestedStructList * newElement_0;
                newElement_0 = [MTRUnitTestingClusterNestedStructList new];
                newElement_0.a = [NSNumber numberWithUnsignedChar:entry_0.a];
                newElement_0.b = [NSNumber numberWithBool:entry_0.b];
                newElement_0.c = [MTRUnitTestingClusterSimpleStruct new];
                newElement_0.c.a = [NSNumber numberWithUnsignedChar:entry_0.c.a];
                newElement_0.c.b = [NSNumber numberWithBool:entry_0.c.b];
                newElement_0.c.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.c)];
                newElement_0.c.d = [NSData dataWithBytes:entry_0.c.d.data() length:entry_0.c.d.size()];
                newElement_0.c.e = [[NSString alloc] initWithBytes:entry_0.c.e.data()
                                                            length:entry_0.c.e.size()
                                                          encoding:NSUTF8StringEncoding];
                newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()];
                newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g];
                newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h];
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.d) {
                        MTRUnitTestingClusterSimpleStruct * newElement_2;
                        newElement_2 = [MTRUnitTestingClusterSimpleStruct new];
                        newElement_2.a = [NSNumber numberWithUnsignedChar:entry_2.a];
                        newElement_2.b = [NSNumber numberWithBool:entry_2.b];
                        newElement_2.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.c)];
                        newElement_2.d = [NSData dataWithBytes:entry_2.d.data() length:entry_2.d.size()];
                        newElement_2.e = [[NSString alloc] initWithBytes:entry_2.e.data()
                                                                  length:entry_2.e.size()
                                                                encoding:NSUTF8StringEncoding];
                        newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()];
                        newElement_2.g = [NSNumber numberWithFloat:entry_2.g];
                        newElement_2.h = [NSNumber numberWithDouble:entry_2.h];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.d = array_2;
                }
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.e) {
                        NSNumber * newElement_2;
                        newElement_2 = [NSNumber numberWithUnsignedInt:entry_2];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.e = array_2;
                }
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.f) {
                        NSData * newElement_2;
                        newElement_2 = [NSData dataWithBytes:entry_2.data() length:entry_2.size()];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.f = array_2;
                }
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.g) {
                        NSNumber * newElement_2;
                        newElement_2 = [NSNumber numberWithUnsignedChar:entry_2];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.g = array_2;
                }
                [array_0 addObject:newElement_0];
            }
            params.arg1 = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                testListNestedStructListArgumentRequestWithParams:params
                                                       completion:^(MTRUnitTestingClusterBooleanResponseParams * _Nullable values,
                                                           NSError * _Nullable error) {
                                                           NSLog(@"Values: %@", values);
                                                           responsesNeeded--;
                                                           if (error != nil) {
                                                               mError = error;
                                                               LogNSError("Error", error);
                                                           }
                                                           if (responsesNeeded == 0) {
                                                               SetCommandExitStatus(mError);
                                                           }
                                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestListNestedStructListArgumentRequest::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::NestedStructList::Type>>
        mComplex_Arg1;
};

/*
 * Command TestListInt8UReverseRequest
 */
class UnitTestingTestListInt8UReverseRequest : public ClusterCommand {
public:
    UnitTestingTestListInt8UReverseRequest()
        : ClusterCommand("test-list-int8ureverse-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestListInt8UReverseRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mRequest.arg1) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithUnsignedChar:entry_0];
                [array_0 addObject:newElement_0];
            }
            params.arg1 = array_0;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                testListInt8UReverseRequestWithParams:params
                                           completion:^(MTRUnitTestingClusterTestListInt8UReverseResponseParams * _Nullable values,
                                               NSError * _Nullable error) {
                                               NSLog(@"Values: %@", values);
                                               responsesNeeded--;
                                               if (error != nil) {
                                                   mError = error;
                                                   LogNSError("Error", error);
                                               }
                                               if (responsesNeeded == 0) {
                                                   SetCommandExitStatus(mError);
                                               }
                                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestListInt8UReverseRequest::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::List<const uint8_t>> mComplex_Arg1;
};

/*
 * Command TestEnumsRequest
 */
class UnitTestingTestEnumsRequest : public ClusterCommand {
public:
    UnitTestingTestEnumsRequest()
        : ClusterCommand("test-enums-request")
    {
        AddArgument("Arg1", 0, UINT16_MAX, &mRequest.arg1);
        AddArgument("Arg2", 0, UINT8_MAX, &mRequest.arg2);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestEnumsRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [NSNumber numberWithUnsignedShort:chip::to_underlying(mRequest.arg1)];
        params.arg2 = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg2)];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testEnumsRequestWithParams:params
                                     completion:^(MTRUnitTestingClusterTestEnumsResponseParams * _Nullable values,
                                         NSError * _Nullable error) {
                                         NSLog(@"Values: %@", values);
                                         responsesNeeded--;
                                         if (error != nil) {
                                             mError = error;
                                             LogNSError("Error", error);
                                         }
                                         if (responsesNeeded == 0) {
                                             SetCommandExitStatus(mError);
                                         }
                                     }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestEnumsRequest::Type mRequest;
};

/*
 * Command TestNullableOptionalRequest
 */
class UnitTestingTestNullableOptionalRequest : public ClusterCommand {
public:
    UnitTestingTestNullableOptionalRequest()
        : ClusterCommand("test-nullable-optional-request")
    {
        AddArgument("Arg1", 0, UINT8_MAX, &mRequest.arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestNullableOptionalRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.arg1.HasValue()) {
            if (mRequest.arg1.Value().IsNull()) {
                params.arg1 = nil;
            } else {
                params.arg1 = [NSNumber numberWithUnsignedChar:mRequest.arg1.Value().Value()];
            }
        } else {
            params.arg1 = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                testNullableOptionalRequestWithParams:params
                                           completion:^(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable values,
                                               NSError * _Nullable error) {
                                               NSLog(@"Values: %@", values);
                                               responsesNeeded--;
                                               if (error != nil) {
                                                   mError = error;
                                                   LogNSError("Error", error);
                                               }
                                               if (responsesNeeded == 0) {
                                                   SetCommandExitStatus(mError);
                                               }
                                           }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestNullableOptionalRequest::Type mRequest;
};

/*
 * Command TestComplexNullableOptionalRequest
 */
class UnitTestingTestComplexNullableOptionalRequest : public ClusterCommand {
public:
    UnitTestingTestComplexNullableOptionalRequest()
        : ClusterCommand("test-complex-nullable-optional-request")
        , mComplex_NullableStruct(&mRequest.nullableStruct)
        , mComplex_OptionalStruct(&mRequest.optionalStruct)
        , mComplex_NullableOptionalStruct(&mRequest.nullableOptionalStruct)
        , mComplex_NullableList(&mRequest.nullableList)
        , mComplex_OptionalList(&mRequest.optionalList)
        , mComplex_NullableOptionalList(&mRequest.nullableOptionalList)
    {
        AddArgument("NullableInt", 0, UINT16_MAX, &mRequest.nullableInt);
        AddArgument("OptionalInt", 0, UINT16_MAX, &mRequest.optionalInt);
        AddArgument("NullableOptionalInt", 0, UINT16_MAX, &mRequest.nullableOptionalInt);
        AddArgument("NullableString", &mRequest.nullableString);
        AddArgument("OptionalString", &mRequest.optionalString);
        AddArgument("NullableOptionalString", &mRequest.nullableOptionalString);
        AddArgument("NullableStruct", &mComplex_NullableStruct);
        AddArgument("OptionalStruct", &mComplex_OptionalStruct);
        AddArgument("NullableOptionalStruct", &mComplex_NullableOptionalStruct);
        AddArgument("NullableList", &mComplex_NullableList);
        AddArgument("OptionalList", &mComplex_OptionalList);
        AddArgument("NullableOptionalList", &mComplex_NullableOptionalList);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestComplexNullableOptionalRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.nullableInt.IsNull()) {
            params.nullableInt = nil;
        } else {
            params.nullableInt = [NSNumber numberWithUnsignedShort:mRequest.nullableInt.Value()];
        }
        if (mRequest.optionalInt.HasValue()) {
            params.optionalInt = [NSNumber numberWithUnsignedShort:mRequest.optionalInt.Value()];
        } else {
            params.optionalInt = nil;
        }
        if (mRequest.nullableOptionalInt.HasValue()) {
            if (mRequest.nullableOptionalInt.Value().IsNull()) {
                params.nullableOptionalInt = nil;
            } else {
                params.nullableOptionalInt = [NSNumber numberWithUnsignedShort:mRequest.nullableOptionalInt.Value().Value()];
            }
        } else {
            params.nullableOptionalInt = nil;
        }
        if (mRequest.nullableString.IsNull()) {
            params.nullableString = nil;
        } else {
            params.nullableString = [[NSString alloc] initWithBytes:mRequest.nullableString.Value().data()
                                                             length:mRequest.nullableString.Value().size()
                                                           encoding:NSUTF8StringEncoding];
        }
        if (mRequest.optionalString.HasValue()) {
            params.optionalString = [[NSString alloc] initWithBytes:mRequest.optionalString.Value().data()
                                                             length:mRequest.optionalString.Value().size()
                                                           encoding:NSUTF8StringEncoding];
        } else {
            params.optionalString = nil;
        }
        if (mRequest.nullableOptionalString.HasValue()) {
            if (mRequest.nullableOptionalString.Value().IsNull()) {
                params.nullableOptionalString = nil;
            } else {
                params.nullableOptionalString =
                    [[NSString alloc] initWithBytes:mRequest.nullableOptionalString.Value().Value().data()
                                             length:mRequest.nullableOptionalString.Value().Value().size()
                                           encoding:NSUTF8StringEncoding];
            }
        } else {
            params.nullableOptionalString = nil;
        }
        if (mRequest.nullableStruct.IsNull()) {
            params.nullableStruct = nil;
        } else {
            params.nullableStruct = [MTRUnitTestingClusterSimpleStruct new];
            params.nullableStruct.a = [NSNumber numberWithUnsignedChar:mRequest.nullableStruct.Value().a];
            params.nullableStruct.b = [NSNumber numberWithBool:mRequest.nullableStruct.Value().b];
            params.nullableStruct.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.nullableStruct.Value().c)];
            params.nullableStruct.d = [NSData dataWithBytes:mRequest.nullableStruct.Value().d.data()
                                                     length:mRequest.nullableStruct.Value().d.size()];
            params.nullableStruct.e = [[NSString alloc] initWithBytes:mRequest.nullableStruct.Value().e.data()
                                                               length:mRequest.nullableStruct.Value().e.size()
                                                             encoding:NSUTF8StringEncoding];
            params.nullableStruct.f = [NSNumber numberWithUnsignedChar:mRequest.nullableStruct.Value().f.Raw()];
            params.nullableStruct.g = [NSNumber numberWithFloat:mRequest.nullableStruct.Value().g];
            params.nullableStruct.h = [NSNumber numberWithDouble:mRequest.nullableStruct.Value().h];
        }
        if (mRequest.optionalStruct.HasValue()) {
            params.optionalStruct = [MTRUnitTestingClusterSimpleStruct new];
            params.optionalStruct.a = [NSNumber numberWithUnsignedChar:mRequest.optionalStruct.Value().a];
            params.optionalStruct.b = [NSNumber numberWithBool:mRequest.optionalStruct.Value().b];
            params.optionalStruct.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.optionalStruct.Value().c)];
            params.optionalStruct.d = [NSData dataWithBytes:mRequest.optionalStruct.Value().d.data()
                                                     length:mRequest.optionalStruct.Value().d.size()];
            params.optionalStruct.e = [[NSString alloc] initWithBytes:mRequest.optionalStruct.Value().e.data()
                                                               length:mRequest.optionalStruct.Value().e.size()
                                                             encoding:NSUTF8StringEncoding];
            params.optionalStruct.f = [NSNumber numberWithUnsignedChar:mRequest.optionalStruct.Value().f.Raw()];
            params.optionalStruct.g = [NSNumber numberWithFloat:mRequest.optionalStruct.Value().g];
            params.optionalStruct.h = [NSNumber numberWithDouble:mRequest.optionalStruct.Value().h];
        } else {
            params.optionalStruct = nil;
        }
        if (mRequest.nullableOptionalStruct.HasValue()) {
            if (mRequest.nullableOptionalStruct.Value().IsNull()) {
                params.nullableOptionalStruct = nil;
            } else {
                params.nullableOptionalStruct = [MTRUnitTestingClusterSimpleStruct new];
                params.nullableOptionalStruct.a =
                    [NSNumber numberWithUnsignedChar:mRequest.nullableOptionalStruct.Value().Value().a];
                params.nullableOptionalStruct.b = [NSNumber numberWithBool:mRequest.nullableOptionalStruct.Value().Value().b];
                params.nullableOptionalStruct.c =
                    [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.nullableOptionalStruct.Value().Value().c)];
                params.nullableOptionalStruct.d = [NSData dataWithBytes:mRequest.nullableOptionalStruct.Value().Value().d.data()
                                                                 length:mRequest.nullableOptionalStruct.Value().Value().d.size()];
                params.nullableOptionalStruct.e =
                    [[NSString alloc] initWithBytes:mRequest.nullableOptionalStruct.Value().Value().e.data()
                                             length:mRequest.nullableOptionalStruct.Value().Value().e.size()
                                           encoding:NSUTF8StringEncoding];
                params.nullableOptionalStruct.f =
                    [NSNumber numberWithUnsignedChar:mRequest.nullableOptionalStruct.Value().Value().f.Raw()];
                params.nullableOptionalStruct.g = [NSNumber numberWithFloat:mRequest.nullableOptionalStruct.Value().Value().g];
                params.nullableOptionalStruct.h = [NSNumber numberWithDouble:mRequest.nullableOptionalStruct.Value().Value().h];
            }
        } else {
            params.nullableOptionalStruct = nil;
        }
        if (mRequest.nullableList.IsNull()) {
            params.nullableList = nil;
        } else {
            { // Scope for our temporary variables
                auto * array_1 = [NSMutableArray new];
                for (auto & entry_1 : mRequest.nullableList.Value()) {
                    NSNumber * newElement_1;
                    newElement_1 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1)];
                    [array_1 addObject:newElement_1];
                }
                params.nullableList = array_1;
            }
        }
        if (mRequest.optionalList.HasValue()) {
            { // Scope for our temporary variables
                auto * array_1 = [NSMutableArray new];
                for (auto & entry_1 : mRequest.optionalList.Value()) {
                    NSNumber * newElement_1;
                    newElement_1 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1)];
                    [array_1 addObject:newElement_1];
                }
                params.optionalList = array_1;
            }
        } else {
            params.optionalList = nil;
        }
        if (mRequest.nullableOptionalList.HasValue()) {
            if (mRequest.nullableOptionalList.Value().IsNull()) {
                params.nullableOptionalList = nil;
            } else {
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : mRequest.nullableOptionalList.Value().Value()) {
                        NSNumber * newElement_2;
                        newElement_2 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2)];
                        [array_2 addObject:newElement_2];
                    }
                    params.nullableOptionalList = array_2;
                }
            }
        } else {
            params.nullableOptionalList = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                testComplexNullableOptionalRequestWithParams:params
                                                  completion:^(
                                                      MTRUnitTestingClusterTestComplexNullableOptionalResponseParams * _Nullable values,
                                                      NSError * _Nullable error) {
                                                      NSLog(@"Values: %@", values);
                                                      responsesNeeded--;
                                                      if (error != nil) {
                                                          mError = error;
                                                          LogNSError("Error", error);
                                                      }
                                                      if (responsesNeeded == 0) {
                                                          SetCommandExitStatus(mError);
                                                      }
                                                  }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestComplexNullableOptionalRequest::Type mRequest;
    TypedComplexArgument<chip::app::DataModel::Nullable<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type>>
        mComplex_NullableStruct;
    TypedComplexArgument<chip::Optional<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type>> mComplex_OptionalStruct;
    TypedComplexArgument<
        chip::Optional<chip::app::DataModel::Nullable<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type>>>
        mComplex_NullableOptionalStruct;
    TypedComplexArgument<
        chip::app::DataModel::Nullable<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::SimpleEnum>>>
        mComplex_NullableList;
    TypedComplexArgument<chip::Optional<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::SimpleEnum>>>
        mComplex_OptionalList;
    TypedComplexArgument<chip::Optional<
        chip::app::DataModel::Nullable<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::SimpleEnum>>>>
        mComplex_NullableOptionalList;
};

/*
 * Command SimpleStructEchoRequest
 */
class UnitTestingSimpleStructEchoRequest : public ClusterCommand {
public:
    UnitTestingSimpleStructEchoRequest()
        : ClusterCommand("simple-struct-echo-request")
        , mComplex_Arg1(&mRequest.arg1)
    {
        AddArgument("Arg1", &mComplex_Arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterSimpleStructEchoRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [MTRUnitTestingClusterSimpleStruct new];
        params.arg1.a = [NSNumber numberWithUnsignedChar:mRequest.arg1.a];
        params.arg1.b = [NSNumber numberWithBool:mRequest.arg1.b];
        params.arg1.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c)];
        params.arg1.d = [NSData dataWithBytes:mRequest.arg1.d.data() length:mRequest.arg1.d.size()];
        params.arg1.e = [[NSString alloc] initWithBytes:mRequest.arg1.e.data()
                                                 length:mRequest.arg1.e.size()
                                               encoding:NSUTF8StringEncoding];
        params.arg1.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.f.Raw()];
        params.arg1.g = [NSNumber numberWithFloat:mRequest.arg1.g];
        params.arg1.h = [NSNumber numberWithDouble:mRequest.arg1.h];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster simpleStructEchoRequestWithParams:params
                                            completion:^(MTRUnitTestingClusterSimpleStructResponseParams * _Nullable values,
                                                NSError * _Nullable error) {
                                                NSLog(@"Values: %@", values);
                                                responsesNeeded--;
                                                if (error != nil) {
                                                    mError = error;
                                                    LogNSError("Error", error);
                                                }
                                                if (responsesNeeded == 0) {
                                                    SetCommandExitStatus(mError);
                                                }
                                            }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::SimpleStructEchoRequest::Type mRequest;
    TypedComplexArgument<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type> mComplex_Arg1;
};

/*
 * Command TimedInvokeRequest
 */
class UnitTestingTimedInvokeRequest : public ClusterCommand {
public:
    UnitTestingTimedInvokeRequest()
        : ClusterCommand("timed-invoke-request")
    {
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTimedInvokeRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster timedInvokeRequestWithParams:params
                                       completion:^(NSError * _Nullable error) {
                                           responsesNeeded--;
                                           if (error != nil) {
                                               mError = error;
                                               LogNSError("Error", error);
                                           }
                                           if (responsesNeeded == 0) {
                                               SetCommandExitStatus(mError);
                                           }
                                       }];
        }
        return CHIP_NO_ERROR;
    }

private:
};

/*
 * Command TestSimpleOptionalArgumentRequest
 */
class UnitTestingTestSimpleOptionalArgumentRequest : public ClusterCommand {
public:
    UnitTestingTestSimpleOptionalArgumentRequest()
        : ClusterCommand("test-simple-optional-argument-request")
    {
        AddArgument("Arg1", 0, 1, &mRequest.arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        if (mRequest.arg1.HasValue()) {
            params.arg1 = [NSNumber numberWithBool:mRequest.arg1.Value()];
        } else {
            params.arg1 = nil;
        }
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testSimpleOptionalArgumentRequestWithParams:params
                                                      completion:^(NSError * _Nullable error) {
                                                          responsesNeeded--;
                                                          if (error != nil) {
                                                              mError = error;
                                                              LogNSError("Error", error);
                                                          }
                                                          if (responsesNeeded == 0) {
                                                              SetCommandExitStatus(mError);
                                                          }
                                                      }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestSimpleOptionalArgumentRequest::Type mRequest;
};

/*
 * Command TestEmitTestEventRequest
 */
class UnitTestingTestEmitTestEventRequest : public ClusterCommand {
public:
    UnitTestingTestEmitTestEventRequest()
        : ClusterCommand("test-emit-test-event-request")
    {
        AddArgument("Arg1", 0, UINT8_MAX, &mRequest.arg1);
        AddArgument("Arg2", 0, UINT8_MAX, &mRequest.arg2);
        AddArgument("Arg3", 0, 1, &mRequest.arg3);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestEmitTestEventRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [NSNumber numberWithUnsignedChar:mRequest.arg1];
        params.arg2 = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg2)];
        params.arg3 = [NSNumber numberWithBool:mRequest.arg3];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster testEmitTestEventRequestWithParams:params
                                             completion:^(MTRUnitTestingClusterTestEmitTestEventResponseParams * _Nullable values,
                                                 NSError * _Nullable error) {
                                                 NSLog(@"Values: %@", values);
                                                 responsesNeeded--;
                                                 if (error != nil) {
                                                     mError = error;
                                                     LogNSError("Error", error);
                                                 }
                                                 if (responsesNeeded == 0) {
                                                     SetCommandExitStatus(mError);
                                                 }
                                             }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestEmitTestEventRequest::Type mRequest;
};

/*
 * Command TestEmitTestFabricScopedEventRequest
 */
class UnitTestingTestEmitTestFabricScopedEventRequest : public ClusterCommand {
public:
    UnitTestingTestEmitTestFabricScopedEventRequest()
        : ClusterCommand("test-emit-test-fabric-scoped-event-request")
    {
        AddArgument("Arg1", 0, UINT8_MAX, &mRequest.arg1);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) command (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams alloc] init];
        params.timedInvokeTimeoutMs
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.arg1 = [NSNumber numberWithUnsignedChar:mRequest.arg1];
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--) {
            [cluster
                testEmitTestFabricScopedEventRequestWithParams:params
                                                    completion:^(
                                                        MTRUnitTestingClusterTestEmitTestFabricScopedEventResponseParams * _Nullable values,
                                                        NSError * _Nullable error) {
                                                        NSLog(@"Values: %@", values);
                                                        responsesNeeded--;
                                                        if (error != nil) {
                                                            mError = error;
                                                            LogNSError("Error", error);
                                                        }
                                                        if (responsesNeeded == 0) {
                                                            SetCommandExitStatus(mError);
                                                        }
                                                    }];
        }
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Commands::TestEmitTestFabricScopedEventRequest::Type mRequest;
};

/*
 * Attribute Boolean
 */
class ReadUnitTestingBoolean : public ReadAttribute {
public:
    ReadUnitTestingBoolean()
        : ReadAttribute("boolean")
    {
    }

    ~ReadUnitTestingBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Boolean response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Boolean read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingBoolean : public WriteAttribute {
public:
    WriteUnitTestingBoolean()
        : WriteAttribute("boolean")
    {
        AddArgument("attr-name", "boolean");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeBooleanWithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("UnitTesting Boolean write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeUnitTestingBoolean : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingBoolean()
        : SubscribeAttribute("boolean")
    {
    }

    ~SubscribeAttributeUnitTestingBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBooleanWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Boolean response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Bitmap8
 */
class ReadUnitTestingBitmap8 : public ReadAttribute {
public:
    ReadUnitTestingBitmap8()
        : ReadAttribute("bitmap8")
    {
    }

    ~ReadUnitTestingBitmap8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBitmap8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Bitmap8 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Bitmap8 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingBitmap8 : public WriteAttribute {
public:
    WriteUnitTestingBitmap8()
        : WriteAttribute("bitmap8")
    {
        AddArgument("attr-name", "bitmap8");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingBitmap8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeBitmap8WithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("UnitTesting Bitmap8 write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingBitmap8 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingBitmap8()
        : SubscribeAttribute("bitmap8")
    {
    }

    ~SubscribeAttributeUnitTestingBitmap8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBitmap8WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Bitmap8 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Bitmap16
 */
class ReadUnitTestingBitmap16 : public ReadAttribute {
public:
    ReadUnitTestingBitmap16()
        : ReadAttribute("bitmap16")
    {
    }

    ~ReadUnitTestingBitmap16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBitmap16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Bitmap16 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Bitmap16 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingBitmap16 : public WriteAttribute {
public:
    WriteUnitTestingBitmap16()
        : WriteAttribute("bitmap16")
    {
        AddArgument("attr-name", "bitmap16");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingBitmap16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeBitmap16WithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("UnitTesting Bitmap16 write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingBitmap16 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingBitmap16()
        : SubscribeAttribute("bitmap16")
    {
    }

    ~SubscribeAttributeUnitTestingBitmap16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBitmap16WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Bitmap16 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Bitmap32
 */
class ReadUnitTestingBitmap32 : public ReadAttribute {
public:
    ReadUnitTestingBitmap32()
        : ReadAttribute("bitmap32")
    {
    }

    ~ReadUnitTestingBitmap32() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBitmap32WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Bitmap32 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Bitmap32 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingBitmap32 : public WriteAttribute {
public:
    WriteUnitTestingBitmap32()
        : WriteAttribute("bitmap32")
    {
        AddArgument("attr-name", "bitmap32");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingBitmap32() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeBitmap32WithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("UnitTesting Bitmap32 write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeUnitTestingBitmap32 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingBitmap32()
        : SubscribeAttribute("bitmap32")
    {
    }

    ~SubscribeAttributeUnitTestingBitmap32() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBitmap32WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Bitmap32 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Bitmap64
 */
class ReadUnitTestingBitmap64 : public ReadAttribute {
public:
    ReadUnitTestingBitmap64()
        : ReadAttribute("bitmap64")
    {
    }

    ~ReadUnitTestingBitmap64() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeBitmap64WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Bitmap64 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Bitmap64 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingBitmap64 : public WriteAttribute {
public:
    WriteUnitTestingBitmap64()
        : WriteAttribute("bitmap64")
    {
        AddArgument("attr-name", "bitmap64");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingBitmap64() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeBitmap64WithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("UnitTesting Bitmap64 write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingBitmap64 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingBitmap64()
        : SubscribeAttribute("bitmap64")
    {
    }

    ~SubscribeAttributeUnitTestingBitmap64() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeBitmap64WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Bitmap64 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int8u
 */
class ReadUnitTestingInt8u : public ReadAttribute {
public:
    ReadUnitTestingInt8u()
        : ReadAttribute("int8u")
    {
    }

    ~ReadUnitTestingInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int8u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int8u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt8u : public WriteAttribute {
public:
    WriteUnitTestingInt8u()
        : WriteAttribute("int8u")
    {
        AddArgument("attr-name", "int8u");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeInt8uWithValue:value
                                       params:params
                                   completion:^(NSError * _Nullable error) {
                                       if (error != nil) {
                                           LogNSError("UnitTesting Int8u write Error", error);
                                       }
                                       SetCommandExitStatus(error);
                                   }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingInt8u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt8u()
        : SubscribeAttribute("int8u")
    {
    }

    ~SubscribeAttributeUnitTestingInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt8uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int8u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int16u
 */
class ReadUnitTestingInt16u : public ReadAttribute {
public:
    ReadUnitTestingInt16u()
        : ReadAttribute("int16u")
    {
    }

    ~ReadUnitTestingInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int16u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int16u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt16u : public WriteAttribute {
public:
    WriteUnitTestingInt16u()
        : WriteAttribute("int16u")
    {
        AddArgument("attr-name", "int16u");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeInt16uWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int16u write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingInt16u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt16u()
        : SubscribeAttribute("int16u")
    {
    }

    ~SubscribeAttributeUnitTestingInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt16uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int16u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int24u
 */
class ReadUnitTestingInt24u : public ReadAttribute {
public:
    ReadUnitTestingInt24u()
        : ReadAttribute("int24u")
    {
    }

    ~ReadUnitTestingInt24u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt24uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int24u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int24u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt24u : public WriteAttribute {
public:
    WriteUnitTestingInt24u()
        : WriteAttribute("int24u")
    {
        AddArgument("attr-name", "int24u");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt24u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeInt24uWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int24u write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeUnitTestingInt24u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt24u()
        : SubscribeAttribute("int24u")
    {
    }

    ~SubscribeAttributeUnitTestingInt24u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt24uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int24u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int32u
 */
class ReadUnitTestingInt32u : public ReadAttribute {
public:
    ReadUnitTestingInt32u()
        : ReadAttribute("int32u")
    {
    }

    ~ReadUnitTestingInt32u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt32uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int32u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int32u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt32u : public WriteAttribute {
public:
    WriteUnitTestingInt32u()
        : WriteAttribute("int32u")
    {
        AddArgument("attr-name", "int32u");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt32u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeInt32uWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int32u write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeUnitTestingInt32u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt32u()
        : SubscribeAttribute("int32u")
    {
    }

    ~SubscribeAttributeUnitTestingInt32u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt32uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int32u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int40u
 */
class ReadUnitTestingInt40u : public ReadAttribute {
public:
    ReadUnitTestingInt40u()
        : ReadAttribute("int40u")
    {
    }

    ~ReadUnitTestingInt40u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt40uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int40u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int40u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt40u : public WriteAttribute {
public:
    WriteUnitTestingInt40u()
        : WriteAttribute("int40u")
    {
        AddArgument("attr-name", "int40u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt40u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeInt40uWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int40u write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingInt40u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt40u()
        : SubscribeAttribute("int40u")
    {
    }

    ~SubscribeAttributeUnitTestingInt40u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt40uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int40u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int48u
 */
class ReadUnitTestingInt48u : public ReadAttribute {
public:
    ReadUnitTestingInt48u()
        : ReadAttribute("int48u")
    {
    }

    ~ReadUnitTestingInt48u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000000A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt48uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int48u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int48u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt48u : public WriteAttribute {
public:
    WriteUnitTestingInt48u()
        : WriteAttribute("int48u")
    {
        AddArgument("attr-name", "int48u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt48u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeInt48uWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int48u write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingInt48u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt48u()
        : SubscribeAttribute("int48u")
    {
    }

    ~SubscribeAttributeUnitTestingInt48u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000000A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt48uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int48u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int56u
 */
class ReadUnitTestingInt56u : public ReadAttribute {
public:
    ReadUnitTestingInt56u()
        : ReadAttribute("int56u")
    {
    }

    ~ReadUnitTestingInt56u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000000B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt56uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int56u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int56u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt56u : public WriteAttribute {
public:
    WriteUnitTestingInt56u()
        : WriteAttribute("int56u")
    {
        AddArgument("attr-name", "int56u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt56u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeInt56uWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int56u write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingInt56u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt56u()
        : SubscribeAttribute("int56u")
    {
    }

    ~SubscribeAttributeUnitTestingInt56u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt56uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int56u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int64u
 */
class ReadUnitTestingInt64u : public ReadAttribute {
public:
    ReadUnitTestingInt64u()
        : ReadAttribute("int64u")
    {
    }

    ~ReadUnitTestingInt64u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000000C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt64uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int64u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int64u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt64u : public WriteAttribute {
public:
    WriteUnitTestingInt64u()
        : WriteAttribute("int64u")
    {
        AddArgument("attr-name", "int64u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt64u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeInt64uWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int64u write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingInt64u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt64u()
        : SubscribeAttribute("int64u")
    {
    }

    ~SubscribeAttributeUnitTestingInt64u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000000C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt64uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int64u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int8s
 */
class ReadUnitTestingInt8s : public ReadAttribute {
public:
    ReadUnitTestingInt8s()
        : ReadAttribute("int8s")
    {
    }

    ~ReadUnitTestingInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000000D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int8s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int8s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt8s : public WriteAttribute {
public:
    WriteUnitTestingInt8s()
        : WriteAttribute("int8s")
    {
        AddArgument("attr-name", "int8s");
        AddArgument("attr-value", INT8_MIN, INT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000000D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithChar:mValue];

        [cluster writeAttributeInt8sWithValue:value
                                       params:params
                                   completion:^(NSError * _Nullable error) {
                                       if (error != nil) {
                                           LogNSError("UnitTesting Int8s write Error", error);
                                       }
                                       SetCommandExitStatus(error);
                                   }];
        return CHIP_NO_ERROR;
    }

private:
    int8_t mValue;
};

class SubscribeAttributeUnitTestingInt8s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt8s()
        : SubscribeAttribute("int8s")
    {
    }

    ~SubscribeAttributeUnitTestingInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000000D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt8sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int8s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int16s
 */
class ReadUnitTestingInt16s : public ReadAttribute {
public:
    ReadUnitTestingInt16s()
        : ReadAttribute("int16s")
    {
    }

    ~ReadUnitTestingInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000000E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int16s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int16s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt16s : public WriteAttribute {
public:
    WriteUnitTestingInt16s()
        : WriteAttribute("int16s")
    {
        AddArgument("attr-name", "int16s");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000000E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeInt16sWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int16s write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeUnitTestingInt16s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt16s()
        : SubscribeAttribute("int16s")
    {
    }

    ~SubscribeAttributeUnitTestingInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000000E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt16sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int16s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int24s
 */
class ReadUnitTestingInt24s : public ReadAttribute {
public:
    ReadUnitTestingInt24s()
        : ReadAttribute("int24s")
    {
    }

    ~ReadUnitTestingInt24s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000000F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt24sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int24s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int24s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt24s : public WriteAttribute {
public:
    WriteUnitTestingInt24s()
        : WriteAttribute("int24s")
    {
        AddArgument("attr-name", "int24s");
        AddArgument("attr-value", INT32_MIN, INT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt24s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithInt:mValue];

        [cluster writeAttributeInt24sWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int24s write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int32_t mValue;
};

class SubscribeAttributeUnitTestingInt24s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt24s()
        : SubscribeAttribute("int24s")
    {
    }

    ~SubscribeAttributeUnitTestingInt24s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000000F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt24sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int24s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int32s
 */
class ReadUnitTestingInt32s : public ReadAttribute {
public:
    ReadUnitTestingInt32s()
        : ReadAttribute("int32s")
    {
    }

    ~ReadUnitTestingInt32s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt32sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int32s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int32s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt32s : public WriteAttribute {
public:
    WriteUnitTestingInt32s()
        : WriteAttribute("int32s")
    {
        AddArgument("attr-name", "int32s");
        AddArgument("attr-value", INT32_MIN, INT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt32s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithInt:mValue];

        [cluster writeAttributeInt32sWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int32s write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int32_t mValue;
};

class SubscribeAttributeUnitTestingInt32s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt32s()
        : SubscribeAttribute("int32s")
    {
    }

    ~SubscribeAttributeUnitTestingInt32s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt32sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int32s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int40s
 */
class ReadUnitTestingInt40s : public ReadAttribute {
public:
    ReadUnitTestingInt40s()
        : ReadAttribute("int40s")
    {
    }

    ~ReadUnitTestingInt40s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt40sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int40s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int40s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt40s : public WriteAttribute {
public:
    WriteUnitTestingInt40s()
        : WriteAttribute("int40s")
    {
        AddArgument("attr-name", "int40s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt40s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeInt40sWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int40s write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingInt40s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt40s()
        : SubscribeAttribute("int40s")
    {
    }

    ~SubscribeAttributeUnitTestingInt40s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt40sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int40s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int48s
 */
class ReadUnitTestingInt48s : public ReadAttribute {
public:
    ReadUnitTestingInt48s()
        : ReadAttribute("int48s")
    {
    }

    ~ReadUnitTestingInt48s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt48sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int48s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int48s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt48s : public WriteAttribute {
public:
    WriteUnitTestingInt48s()
        : WriteAttribute("int48s")
    {
        AddArgument("attr-name", "int48s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt48s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeInt48sWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int48s write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingInt48s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt48s()
        : SubscribeAttribute("int48s")
    {
    }

    ~SubscribeAttributeUnitTestingInt48s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt48sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int48s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int56s
 */
class ReadUnitTestingInt56s : public ReadAttribute {
public:
    ReadUnitTestingInt56s()
        : ReadAttribute("int56s")
    {
    }

    ~ReadUnitTestingInt56s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt56sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int56s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int56s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt56s : public WriteAttribute {
public:
    WriteUnitTestingInt56s()
        : WriteAttribute("int56s")
    {
        AddArgument("attr-name", "int56s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt56s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeInt56sWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int56s write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingInt56s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt56s()
        : SubscribeAttribute("int56s")
    {
    }

    ~SubscribeAttributeUnitTestingInt56s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt56sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int56s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Int64s
 */
class ReadUnitTestingInt64s : public ReadAttribute {
public:
    ReadUnitTestingInt64s()
        : ReadAttribute("int64s")
    {
    }

    ~ReadUnitTestingInt64s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeInt64sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Int64s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Int64s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingInt64s : public WriteAttribute {
public:
    WriteUnitTestingInt64s()
        : WriteAttribute("int64s")
    {
        AddArgument("attr-name", "int64s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingInt64s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeInt64sWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Int64s write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingInt64s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingInt64s()
        : SubscribeAttribute("int64s")
    {
    }

    ~SubscribeAttributeUnitTestingInt64s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeInt64sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Int64s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Enum8
 */
class ReadUnitTestingEnum8 : public ReadAttribute {
public:
    ReadUnitTestingEnum8()
        : ReadAttribute("enum8")
    {
    }

    ~ReadUnitTestingEnum8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeEnum8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Enum8 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Enum8 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingEnum8 : public WriteAttribute {
public:
    WriteUnitTestingEnum8()
        : WriteAttribute("enum8")
    {
        AddArgument("attr-name", "enum8");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingEnum8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeEnum8WithValue:value
                                       params:params
                                   completion:^(NSError * _Nullable error) {
                                       if (error != nil) {
                                           LogNSError("UnitTesting Enum8 write Error", error);
                                       }
                                       SetCommandExitStatus(error);
                                   }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingEnum8 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingEnum8()
        : SubscribeAttribute("enum8")
    {
    }

    ~SubscribeAttributeUnitTestingEnum8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnum8WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Enum8 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Enum16
 */
class ReadUnitTestingEnum16 : public ReadAttribute {
public:
    ReadUnitTestingEnum16()
        : ReadAttribute("enum16")
    {
    }

    ~ReadUnitTestingEnum16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeEnum16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Enum16 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Enum16 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingEnum16 : public WriteAttribute {
public:
    WriteUnitTestingEnum16()
        : WriteAttribute("enum16")
    {
        AddArgument("attr-name", "enum16");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingEnum16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeEnum16WithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting Enum16 write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingEnum16 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingEnum16()
        : SubscribeAttribute("enum16")
    {
    }

    ~SubscribeAttributeUnitTestingEnum16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnum16WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Enum16 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FloatSingle
 */
class ReadUnitTestingFloatSingle : public ReadAttribute {
public:
    ReadUnitTestingFloatSingle()
        : ReadAttribute("float-single")
    {
    }

    ~ReadUnitTestingFloatSingle() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeFloatSingleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.FloatSingle response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting FloatSingle read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingFloatSingle : public WriteAttribute {
public:
    WriteUnitTestingFloatSingle()
        : WriteAttribute("float-single")
    {
        AddArgument("attr-name", "float-single");
        AddArgument("attr-value", -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingFloatSingle() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithFloat:mValue];

        [cluster writeAttributeFloatSingleWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("UnitTesting FloatSingle write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    float mValue;
};

class SubscribeAttributeUnitTestingFloatSingle : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingFloatSingle()
        : SubscribeAttribute("float-single")
    {
    }

    ~SubscribeAttributeUnitTestingFloatSingle() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFloatSingleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.FloatSingle response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FloatDouble
 */
class ReadUnitTestingFloatDouble : public ReadAttribute {
public:
    ReadUnitTestingFloatDouble()
        : ReadAttribute("float-double")
    {
    }

    ~ReadUnitTestingFloatDouble() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000018) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeFloatDoubleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.FloatDouble response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting FloatDouble read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingFloatDouble : public WriteAttribute {
public:
    WriteUnitTestingFloatDouble()
        : WriteAttribute("float-double")
    {
        AddArgument("attr-name", "float-double");
        AddArgument("attr-value", -std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingFloatDouble() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithDouble:mValue];

        [cluster writeAttributeFloatDoubleWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("UnitTesting FloatDouble write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    double mValue;
};

class SubscribeAttributeUnitTestingFloatDouble : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingFloatDouble()
        : SubscribeAttribute("float-double")
    {
    }

    ~SubscribeAttributeUnitTestingFloatDouble() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFloatDoubleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.FloatDouble response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute OctetString
 */
class ReadUnitTestingOctetString : public ReadAttribute {
public:
    ReadUnitTestingOctetString()
        : ReadAttribute("octet-string")
    {
    }

    ~ReadUnitTestingOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000019) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeOctetStringWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.OctetString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting OctetString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingOctetString : public WriteAttribute {
public:
    WriteUnitTestingOctetString()
        : WriteAttribute("octet-string")
    {
        AddArgument("attr-name", "octet-string");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSData * _Nonnull value = [[NSData alloc] initWithBytes:mValue.data() length:mValue.size()];

        [cluster writeAttributeOctetStringWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("UnitTesting OctetString write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeUnitTestingOctetString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingOctetString()
        : SubscribeAttribute("octet-string")
    {
    }

    ~SubscribeAttributeUnitTestingOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeOctetStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.OctetString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ListInt8u
 */
class ReadUnitTestingListInt8u : public ReadAttribute {
public:
    ReadUnitTestingListInt8u()
        : ReadAttribute("list-int8u")
    {
    }

    ~ReadUnitTestingListInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000001A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeListInt8uWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.ListInt8u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting ListInt8u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingListInt8u : public WriteAttribute {
public:
    WriteUnitTestingListInt8u()
        : WriteAttribute("list-int8u")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "list-int8u");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingListInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                NSNumber * newElement_0;
                newElement_0 = [NSNumber numberWithUnsignedChar:entry_0];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeListInt8uWithValue:value
                                           params:params
                                       completion:^(NSError * _Nullable error) {
                                           if (error != nil) {
                                               LogNSError("UnitTesting ListInt8u write Error", error);
                                           }
                                           SetCommandExitStatus(error);
                                       }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const uint8_t> mValue;
    TypedComplexArgument<chip::app::DataModel::List<const uint8_t>> mComplex;
};

class SubscribeAttributeUnitTestingListInt8u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingListInt8u()
        : SubscribeAttribute("list-int8u")
    {
    }

    ~SubscribeAttributeUnitTestingListInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000001A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeListInt8uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ListInt8u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ListOctetString
 */
class ReadUnitTestingListOctetString : public ReadAttribute {
public:
    ReadUnitTestingListOctetString()
        : ReadAttribute("list-octet-string")
    {
    }

    ~ReadUnitTestingListOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000001B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeListOctetStringWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.ListOctetString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting ListOctetString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingListOctetString : public WriteAttribute {
public:
    WriteUnitTestingListOctetString()
        : WriteAttribute("list-octet-string")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "list-octet-string");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingListOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                NSData * newElement_0;
                newElement_0 = [NSData dataWithBytes:entry_0.data() length:entry_0.size()];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeListOctetStringWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("UnitTesting ListOctetString write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::ByteSpan> mValue;
    TypedComplexArgument<chip::app::DataModel::List<const chip::ByteSpan>> mComplex;
};

class SubscribeAttributeUnitTestingListOctetString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingListOctetString()
        : SubscribeAttribute("list-octet-string")
    {
    }

    ~SubscribeAttributeUnitTestingListOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000001B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeListOctetStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ListOctetString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ListStructOctetString
 */
class ReadUnitTestingListStructOctetString : public ReadAttribute {
public:
    ReadUnitTestingListStructOctetString()
        : ReadAttribute("list-struct-octet-string")
    {
    }

    ~ReadUnitTestingListStructOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000001C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeListStructOctetStringWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.ListStructOctetString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting ListStructOctetString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingListStructOctetString : public WriteAttribute {
public:
    WriteUnitTestingListStructOctetString()
        : WriteAttribute("list-struct-octet-string")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "list-struct-octet-string");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingListStructOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRUnitTestingClusterTestListStructOctet * newElement_0;
                newElement_0 = [MTRUnitTestingClusterTestListStructOctet new];
                newElement_0.member1 = [NSNumber numberWithUnsignedLongLong:entry_0.member1];
                newElement_0.member2 = [NSData dataWithBytes:entry_0.member2.data() length:entry_0.member2.size()];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeListStructOctetStringWithValue:value
                                                       params:params
                                                   completion:^(NSError * _Nullable error) {
                                                       if (error != nil) {
                                                           LogNSError("UnitTesting ListStructOctetString write Error", error);
                                                       }
                                                       SetCommandExitStatus(error);
                                                   }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::TestListStructOctet::Type> mValue;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::TestListStructOctet::Type>>
        mComplex;
};

class SubscribeAttributeUnitTestingListStructOctetString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingListStructOctetString()
        : SubscribeAttribute("list-struct-octet-string")
    {
    }

    ~SubscribeAttributeUnitTestingListStructOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000001C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeListStructOctetStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ListStructOctetString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LongOctetString
 */
class ReadUnitTestingLongOctetString : public ReadAttribute {
public:
    ReadUnitTestingLongOctetString()
        : ReadAttribute("long-octet-string")
    {
    }

    ~ReadUnitTestingLongOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000001D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeLongOctetStringWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.LongOctetString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting LongOctetString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingLongOctetString : public WriteAttribute {
public:
    WriteUnitTestingLongOctetString()
        : WriteAttribute("long-octet-string")
    {
        AddArgument("attr-name", "long-octet-string");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingLongOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000001D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSData * _Nonnull value = [[NSData alloc] initWithBytes:mValue.data() length:mValue.size()];

        [cluster writeAttributeLongOctetStringWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("UnitTesting LongOctetString write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeUnitTestingLongOctetString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingLongOctetString()
        : SubscribeAttribute("long-octet-string")
    {
    }

    ~SubscribeAttributeUnitTestingLongOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000001D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLongOctetStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.LongOctetString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute CharString
 */
class ReadUnitTestingCharString : public ReadAttribute {
public:
    ReadUnitTestingCharString()
        : ReadAttribute("char-string")
    {
    }

    ~ReadUnitTestingCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000001E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeCharStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.CharString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting CharString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingCharString : public WriteAttribute {
public:
    WriteUnitTestingCharString()
        : WriteAttribute("char-string")
    {
        AddArgument("attr-name", "char-string");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000001E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeCharStringWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("UnitTesting CharString write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeUnitTestingCharString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingCharString()
        : SubscribeAttribute("char-string")
    {
    }

    ~SubscribeAttributeUnitTestingCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000001E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeCharStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.CharString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute LongCharString
 */
class ReadUnitTestingLongCharString : public ReadAttribute {
public:
    ReadUnitTestingLongCharString()
        : ReadAttribute("long-char-string")
    {
    }

    ~ReadUnitTestingLongCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000001F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeLongCharStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.LongCharString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting LongCharString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingLongCharString : public WriteAttribute {
public:
    WriteUnitTestingLongCharString()
        : WriteAttribute("long-char-string")
    {
        AddArgument("attr-name", "long-char-string");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingLongCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000001F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nonnull value = [[NSString alloc] initWithBytes:mValue.data()
                                                             length:mValue.size()
                                                           encoding:NSUTF8StringEncoding];

        [cluster writeAttributeLongCharStringWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting LongCharString write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeUnitTestingLongCharString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingLongCharString()
        : SubscribeAttribute("long-char-string")
    {
    }

    ~SubscribeAttributeUnitTestingLongCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000001F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeLongCharStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.LongCharString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EpochUs
 */
class ReadUnitTestingEpochUs : public ReadAttribute {
public:
    ReadUnitTestingEpochUs()
        : ReadAttribute("epoch-us")
    {
    }

    ~ReadUnitTestingEpochUs() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000020) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeEpochUsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.EpochUs response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting EpochUs read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingEpochUs : public WriteAttribute {
public:
    WriteUnitTestingEpochUs()
        : WriteAttribute("epoch-us")
    {
        AddArgument("attr-name", "epoch-us");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingEpochUs() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeEpochUsWithValue:value
                                         params:params
                                     completion:^(NSError * _Nullable error) {
                                         if (error != nil) {
                                             LogNSError("UnitTesting EpochUs write Error", error);
                                         }
                                         SetCommandExitStatus(error);
                                     }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingEpochUs : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingEpochUs()
        : SubscribeAttribute("epoch-us")
    {
    }

    ~SubscribeAttributeUnitTestingEpochUs() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000020) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEpochUsWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.EpochUs response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EpochS
 */
class ReadUnitTestingEpochS : public ReadAttribute {
public:
    ReadUnitTestingEpochS()
        : ReadAttribute("epoch-s")
    {
    }

    ~ReadUnitTestingEpochS() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000021) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeEpochSWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.EpochS response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting EpochS read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingEpochS : public WriteAttribute {
public:
    WriteUnitTestingEpochS()
        : WriteAttribute("epoch-s")
    {
        AddArgument("attr-name", "epoch-s");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingEpochS() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeEpochSWithValue:value
                                        params:params
                                    completion:^(NSError * _Nullable error) {
                                        if (error != nil) {
                                            LogNSError("UnitTesting EpochS write Error", error);
                                        }
                                        SetCommandExitStatus(error);
                                    }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeUnitTestingEpochS : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingEpochS()
        : SubscribeAttribute("epoch-s")
    {
    }

    ~SubscribeAttributeUnitTestingEpochS() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000021) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEpochSWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.EpochS response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute VendorId
 */
class ReadUnitTestingVendorId : public ReadAttribute {
public:
    ReadUnitTestingVendorId()
        : ReadAttribute("vendor-id")
    {
    }

    ~ReadUnitTestingVendorId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000022) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeVendorIdWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.VendorId response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting VendorId read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingVendorId : public WriteAttribute {
public:
    WriteUnitTestingVendorId()
        : WriteAttribute("vendor-id")
    {
        AddArgument("attr-name", "vendor-id");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingVendorId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeVendorIdWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("UnitTesting VendorId write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    chip::VendorId mValue;
};

class SubscribeAttributeUnitTestingVendorId : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingVendorId()
        : SubscribeAttribute("vendor-id")
    {
    }

    ~SubscribeAttributeUnitTestingVendorId() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000022) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeVendorIdWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.VendorId response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ListNullablesAndOptionalsStruct
 */
class ReadUnitTestingListNullablesAndOptionalsStruct : public ReadAttribute {
public:
    ReadUnitTestingListNullablesAndOptionalsStruct()
        : ReadAttribute("list-nullables-and-optionals-struct")
    {
    }

    ~ReadUnitTestingListNullablesAndOptionalsStruct() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000023) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster
            readAttributeListNullablesAndOptionalsStructWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ListNullablesAndOptionalsStruct response %@", [value description]);
                if (error != nil) {
                    LogNSError("UnitTesting ListNullablesAndOptionalsStruct read Error", error);
                }
                SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingListNullablesAndOptionalsStruct : public WriteAttribute {
public:
    WriteUnitTestingListNullablesAndOptionalsStruct()
        : WriteAttribute("list-nullables-and-optionals-struct")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "list-nullables-and-optionals-struct");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingListNullablesAndOptionalsStruct() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000023) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRUnitTestingClusterNullablesAndOptionalsStruct * newElement_0;
                newElement_0 = [MTRUnitTestingClusterNullablesAndOptionalsStruct new];
                if (entry_0.nullableInt.IsNull()) {
                    newElement_0.nullableInt = nil;
                } else {
                    newElement_0.nullableInt = [NSNumber numberWithUnsignedShort:entry_0.nullableInt.Value()];
                }
                if (entry_0.optionalInt.HasValue()) {
                    newElement_0.optionalInt = [NSNumber numberWithUnsignedShort:entry_0.optionalInt.Value()];
                } else {
                    newElement_0.optionalInt = nil;
                }
                if (entry_0.nullableOptionalInt.HasValue()) {
                    if (entry_0.nullableOptionalInt.Value().IsNull()) {
                        newElement_0.nullableOptionalInt = nil;
                    } else {
                        newElement_0.nullableOptionalInt =
                            [NSNumber numberWithUnsignedShort:entry_0.nullableOptionalInt.Value().Value()];
                    }
                } else {
                    newElement_0.nullableOptionalInt = nil;
                }
                if (entry_0.nullableString.IsNull()) {
                    newElement_0.nullableString = nil;
                } else {
                    newElement_0.nullableString = [[NSString alloc] initWithBytes:entry_0.nullableString.Value().data()
                                                                           length:entry_0.nullableString.Value().size()
                                                                         encoding:NSUTF8StringEncoding];
                }
                if (entry_0.optionalString.HasValue()) {
                    newElement_0.optionalString = [[NSString alloc] initWithBytes:entry_0.optionalString.Value().data()
                                                                           length:entry_0.optionalString.Value().size()
                                                                         encoding:NSUTF8StringEncoding];
                } else {
                    newElement_0.optionalString = nil;
                }
                if (entry_0.nullableOptionalString.HasValue()) {
                    if (entry_0.nullableOptionalString.Value().IsNull()) {
                        newElement_0.nullableOptionalString = nil;
                    } else {
                        newElement_0.nullableOptionalString =
                            [[NSString alloc] initWithBytes:entry_0.nullableOptionalString.Value().Value().data()
                                                     length:entry_0.nullableOptionalString.Value().Value().size()
                                                   encoding:NSUTF8StringEncoding];
                    }
                } else {
                    newElement_0.nullableOptionalString = nil;
                }
                if (entry_0.nullableStruct.IsNull()) {
                    newElement_0.nullableStruct = nil;
                } else {
                    newElement_0.nullableStruct = [MTRUnitTestingClusterSimpleStruct new];
                    newElement_0.nullableStruct.a = [NSNumber numberWithUnsignedChar:entry_0.nullableStruct.Value().a];
                    newElement_0.nullableStruct.b = [NSNumber numberWithBool:entry_0.nullableStruct.Value().b];
                    newElement_0.nullableStruct.c =
                        [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableStruct.Value().c)];
                    newElement_0.nullableStruct.d = [NSData dataWithBytes:entry_0.nullableStruct.Value().d.data()
                                                                   length:entry_0.nullableStruct.Value().d.size()];
                    newElement_0.nullableStruct.e = [[NSString alloc] initWithBytes:entry_0.nullableStruct.Value().e.data()
                                                                             length:entry_0.nullableStruct.Value().e.size()
                                                                           encoding:NSUTF8StringEncoding];
                    newElement_0.nullableStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableStruct.Value().f.Raw()];
                    newElement_0.nullableStruct.g = [NSNumber numberWithFloat:entry_0.nullableStruct.Value().g];
                    newElement_0.nullableStruct.h = [NSNumber numberWithDouble:entry_0.nullableStruct.Value().h];
                }
                if (entry_0.optionalStruct.HasValue()) {
                    newElement_0.optionalStruct = [MTRUnitTestingClusterSimpleStruct new];
                    newElement_0.optionalStruct.a = [NSNumber numberWithUnsignedChar:entry_0.optionalStruct.Value().a];
                    newElement_0.optionalStruct.b = [NSNumber numberWithBool:entry_0.optionalStruct.Value().b];
                    newElement_0.optionalStruct.c =
                        [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.optionalStruct.Value().c)];
                    newElement_0.optionalStruct.d = [NSData dataWithBytes:entry_0.optionalStruct.Value().d.data()
                                                                   length:entry_0.optionalStruct.Value().d.size()];
                    newElement_0.optionalStruct.e = [[NSString alloc] initWithBytes:entry_0.optionalStruct.Value().e.data()
                                                                             length:entry_0.optionalStruct.Value().e.size()
                                                                           encoding:NSUTF8StringEncoding];
                    newElement_0.optionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.optionalStruct.Value().f.Raw()];
                    newElement_0.optionalStruct.g = [NSNumber numberWithFloat:entry_0.optionalStruct.Value().g];
                    newElement_0.optionalStruct.h = [NSNumber numberWithDouble:entry_0.optionalStruct.Value().h];
                } else {
                    newElement_0.optionalStruct = nil;
                }
                if (entry_0.nullableOptionalStruct.HasValue()) {
                    if (entry_0.nullableOptionalStruct.Value().IsNull()) {
                        newElement_0.nullableOptionalStruct = nil;
                    } else {
                        newElement_0.nullableOptionalStruct = [MTRUnitTestingClusterSimpleStruct new];
                        newElement_0.nullableOptionalStruct.a =
                            [NSNumber numberWithUnsignedChar:entry_0.nullableOptionalStruct.Value().Value().a];
                        newElement_0.nullableOptionalStruct.b =
                            [NSNumber numberWithBool:entry_0.nullableOptionalStruct.Value().Value().b];
                        newElement_0.nullableOptionalStruct.c =
                            [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableOptionalStruct.Value().Value().c)];
                        newElement_0.nullableOptionalStruct.d =
                            [NSData dataWithBytes:entry_0.nullableOptionalStruct.Value().Value().d.data()
                                           length:entry_0.nullableOptionalStruct.Value().Value().d.size()];
                        newElement_0.nullableOptionalStruct.e =
                            [[NSString alloc] initWithBytes:entry_0.nullableOptionalStruct.Value().Value().e.data()
                                                     length:entry_0.nullableOptionalStruct.Value().Value().e.size()
                                                   encoding:NSUTF8StringEncoding];
                        newElement_0.nullableOptionalStruct.f =
                            [NSNumber numberWithUnsignedChar:entry_0.nullableOptionalStruct.Value().Value().f.Raw()];
                        newElement_0.nullableOptionalStruct.g =
                            [NSNumber numberWithFloat:entry_0.nullableOptionalStruct.Value().Value().g];
                        newElement_0.nullableOptionalStruct.h =
                            [NSNumber numberWithDouble:entry_0.nullableOptionalStruct.Value().Value().h];
                    }
                } else {
                    newElement_0.nullableOptionalStruct = nil;
                }
                if (entry_0.nullableList.IsNull()) {
                    newElement_0.nullableList = nil;
                } else {
                    { // Scope for our temporary variables
                        auto * array_3 = [NSMutableArray new];
                        for (auto & entry_3 : entry_0.nullableList.Value()) {
                            NSNumber * newElement_3;
                            newElement_3 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_3)];
                            [array_3 addObject:newElement_3];
                        }
                        newElement_0.nullableList = array_3;
                    }
                }
                if (entry_0.optionalList.HasValue()) {
                    { // Scope for our temporary variables
                        auto * array_3 = [NSMutableArray new];
                        for (auto & entry_3 : entry_0.optionalList.Value()) {
                            NSNumber * newElement_3;
                            newElement_3 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_3)];
                            [array_3 addObject:newElement_3];
                        }
                        newElement_0.optionalList = array_3;
                    }
                } else {
                    newElement_0.optionalList = nil;
                }
                if (entry_0.nullableOptionalList.HasValue()) {
                    if (entry_0.nullableOptionalList.Value().IsNull()) {
                        newElement_0.nullableOptionalList = nil;
                    } else {
                        { // Scope for our temporary variables
                            auto * array_4 = [NSMutableArray new];
                            for (auto & entry_4 : entry_0.nullableOptionalList.Value().Value()) {
                                NSNumber * newElement_4;
                                newElement_4 = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_4)];
                                [array_4 addObject:newElement_4];
                            }
                            newElement_0.nullableOptionalList = array_4;
                        }
                    }
                } else {
                    newElement_0.nullableOptionalList = nil;
                }
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeListNullablesAndOptionalsStructWithValue:value
                                                                 params:params
                                                             completion:^(NSError * _Nullable error) {
                                                                 if (error != nil) {
                                                                     LogNSError(
                                                                         "UnitTesting ListNullablesAndOptionalsStruct write Error",
                                                                         error);
                                                                 }
                                                                 SetCommandExitStatus(error);
                                                             }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::NullablesAndOptionalsStruct::Type> mValue;
    TypedComplexArgument<
        chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::NullablesAndOptionalsStruct::Type>>
        mComplex;
};

class SubscribeAttributeUnitTestingListNullablesAndOptionalsStruct : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingListNullablesAndOptionalsStruct()
        : SubscribeAttribute("list-nullables-and-optionals-struct")
    {
    }

    ~SubscribeAttributeUnitTestingListNullablesAndOptionalsStruct() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000023) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeListNullablesAndOptionalsStructWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ListNullablesAndOptionalsStruct response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EnumAttr
 */
class ReadUnitTestingEnumAttr : public ReadAttribute {
public:
    ReadUnitTestingEnumAttr()
        : ReadAttribute("enum-attr")
    {
    }

    ~ReadUnitTestingEnumAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000024) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeEnumAttrWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.EnumAttr response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting EnumAttr read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingEnumAttr : public WriteAttribute {
public:
    WriteUnitTestingEnumAttr()
        : WriteAttribute("enum-attr")
    {
        AddArgument("attr-name", "enum-attr");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingEnumAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeEnumAttrWithValue:value
                                          params:params
                                      completion:^(NSError * _Nullable error) {
                                          if (error != nil) {
                                              LogNSError("UnitTesting EnumAttr write Error", error);
                                          }
                                          SetCommandExitStatus(error);
                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingEnumAttr : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingEnumAttr()
        : SubscribeAttribute("enum-attr")
    {
    }

    ~SubscribeAttributeUnitTestingEnumAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeEnumAttrWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.EnumAttr response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute StructAttr
 */
class ReadUnitTestingStructAttr : public ReadAttribute {
public:
    ReadUnitTestingStructAttr()
        : ReadAttribute("struct-attr")
    {
    }

    ~ReadUnitTestingStructAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000025) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeStructAttrWithCompletion:^(
            MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.StructAttr response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting StructAttr read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingStructAttr : public WriteAttribute {
public:
    WriteUnitTestingStructAttr()
        : WriteAttribute("struct-attr")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "struct-attr");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingStructAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        MTRUnitTestingClusterSimpleStruct * _Nonnull value;
        value = [MTRUnitTestingClusterSimpleStruct new];
        value.a = [NSNumber numberWithUnsignedChar:mValue.a];
        value.b = [NSNumber numberWithBool:mValue.b];
        value.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.c)];
        value.d = [NSData dataWithBytes:mValue.d.data() length:mValue.d.size()];
        value.e = [[NSString alloc] initWithBytes:mValue.e.data() length:mValue.e.size() encoding:NSUTF8StringEncoding];
        value.f = [NSNumber numberWithUnsignedChar:mValue.f.Raw()];
        value.g = [NSNumber numberWithFloat:mValue.g];
        value.h = [NSNumber numberWithDouble:mValue.h];

        [cluster writeAttributeStructAttrWithValue:value
                                            params:params
                                        completion:^(NSError * _Nullable error) {
                                            if (error != nil) {
                                                LogNSError("UnitTesting StructAttr write Error", error);
                                            }
                                            SetCommandExitStatus(error);
                                        }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type mValue;
    TypedComplexArgument<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type> mComplex;
};

class SubscribeAttributeUnitTestingStructAttr : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingStructAttr()
        : SubscribeAttribute("struct-attr")
    {
    }

    ~SubscribeAttributeUnitTestingStructAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeStructAttrWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.StructAttr response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RangeRestrictedInt8u
 */
class ReadUnitTestingRangeRestrictedInt8u : public ReadAttribute {
public:
    ReadUnitTestingRangeRestrictedInt8u()
        : ReadAttribute("range-restricted-int8u")
    {
    }

    ~ReadUnitTestingRangeRestrictedInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000026) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeRangeRestrictedInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.RangeRestrictedInt8u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting RangeRestrictedInt8u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingRangeRestrictedInt8u : public WriteAttribute {
public:
    WriteUnitTestingRangeRestrictedInt8u()
        : WriteAttribute("range-restricted-int8u")
    {
        AddArgument("attr-name", "range-restricted-int8u");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingRangeRestrictedInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000026) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeRangeRestrictedInt8uWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("UnitTesting RangeRestrictedInt8u write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingRangeRestrictedInt8u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingRangeRestrictedInt8u()
        : SubscribeAttribute("range-restricted-int8u")
    {
    }

    ~SubscribeAttributeUnitTestingRangeRestrictedInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000026) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRangeRestrictedInt8uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.RangeRestrictedInt8u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RangeRestrictedInt8s
 */
class ReadUnitTestingRangeRestrictedInt8s : public ReadAttribute {
public:
    ReadUnitTestingRangeRestrictedInt8s()
        : ReadAttribute("range-restricted-int8s")
    {
    }

    ~ReadUnitTestingRangeRestrictedInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000027) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeRangeRestrictedInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.RangeRestrictedInt8s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting RangeRestrictedInt8s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingRangeRestrictedInt8s : public WriteAttribute {
public:
    WriteUnitTestingRangeRestrictedInt8s()
        : WriteAttribute("range-restricted-int8s")
    {
        AddArgument("attr-name", "range-restricted-int8s");
        AddArgument("attr-value", INT8_MIN, INT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingRangeRestrictedInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000027) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithChar:mValue];

        [cluster writeAttributeRangeRestrictedInt8sWithValue:value
                                                      params:params
                                                  completion:^(NSError * _Nullable error) {
                                                      if (error != nil) {
                                                          LogNSError("UnitTesting RangeRestrictedInt8s write Error", error);
                                                      }
                                                      SetCommandExitStatus(error);
                                                  }];
        return CHIP_NO_ERROR;
    }

private:
    int8_t mValue;
};

class SubscribeAttributeUnitTestingRangeRestrictedInt8s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingRangeRestrictedInt8s()
        : SubscribeAttribute("range-restricted-int8s")
    {
    }

    ~SubscribeAttributeUnitTestingRangeRestrictedInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000027) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRangeRestrictedInt8sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.RangeRestrictedInt8s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RangeRestrictedInt16u
 */
class ReadUnitTestingRangeRestrictedInt16u : public ReadAttribute {
public:
    ReadUnitTestingRangeRestrictedInt16u()
        : ReadAttribute("range-restricted-int16u")
    {
    }

    ~ReadUnitTestingRangeRestrictedInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000028) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeRangeRestrictedInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.RangeRestrictedInt16u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting RangeRestrictedInt16u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingRangeRestrictedInt16u : public WriteAttribute {
public:
    WriteUnitTestingRangeRestrictedInt16u()
        : WriteAttribute("range-restricted-int16u")
    {
        AddArgument("attr-name", "range-restricted-int16u");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingRangeRestrictedInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeRangeRestrictedInt16uWithValue:value
                                                       params:params
                                                   completion:^(NSError * _Nullable error) {
                                                       if (error != nil) {
                                                           LogNSError("UnitTesting RangeRestrictedInt16u write Error", error);
                                                       }
                                                       SetCommandExitStatus(error);
                                                   }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingRangeRestrictedInt16u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingRangeRestrictedInt16u()
        : SubscribeAttribute("range-restricted-int16u")
    {
    }

    ~SubscribeAttributeUnitTestingRangeRestrictedInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRangeRestrictedInt16uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.RangeRestrictedInt16u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute RangeRestrictedInt16s
 */
class ReadUnitTestingRangeRestrictedInt16s : public ReadAttribute {
public:
    ReadUnitTestingRangeRestrictedInt16s()
        : ReadAttribute("range-restricted-int16s")
    {
    }

    ~ReadUnitTestingRangeRestrictedInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000029) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeRangeRestrictedInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.RangeRestrictedInt16s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting RangeRestrictedInt16s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingRangeRestrictedInt16s : public WriteAttribute {
public:
    WriteUnitTestingRangeRestrictedInt16s()
        : WriteAttribute("range-restricted-int16s")
    {
        AddArgument("attr-name", "range-restricted-int16s");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingRangeRestrictedInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeRangeRestrictedInt16sWithValue:value
                                                       params:params
                                                   completion:^(NSError * _Nullable error) {
                                                       if (error != nil) {
                                                           LogNSError("UnitTesting RangeRestrictedInt16s write Error", error);
                                                       }
                                                       SetCommandExitStatus(error);
                                                   }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeUnitTestingRangeRestrictedInt16s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingRangeRestrictedInt16s()
        : SubscribeAttribute("range-restricted-int16s")
    {
    }

    ~SubscribeAttributeUnitTestingRangeRestrictedInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeRangeRestrictedInt16sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.RangeRestrictedInt16s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ListLongOctetString
 */
class ReadUnitTestingListLongOctetString : public ReadAttribute {
public:
    ReadUnitTestingListLongOctetString()
        : ReadAttribute("list-long-octet-string")
    {
    }

    ~ReadUnitTestingListLongOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000002A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeListLongOctetStringWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.ListLongOctetString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting ListLongOctetString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingListLongOctetString : public WriteAttribute {
public:
    WriteUnitTestingListLongOctetString()
        : WriteAttribute("list-long-octet-string")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "list-long-octet-string");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingListLongOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000002A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                NSData * newElement_0;
                newElement_0 = [NSData dataWithBytes:entry_0.data() length:entry_0.size()];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeListLongOctetStringWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("UnitTesting ListLongOctetString write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::ByteSpan> mValue;
    TypedComplexArgument<chip::app::DataModel::List<const chip::ByteSpan>> mComplex;
};

class SubscribeAttributeUnitTestingListLongOctetString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingListLongOctetString()
        : SubscribeAttribute("list-long-octet-string")
    {
    }

    ~SubscribeAttributeUnitTestingListLongOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000002A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeListLongOctetStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ListLongOctetString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ListFabricScoped
 */
class ReadUnitTestingListFabricScoped : public ReadAttribute {
public:
    ReadUnitTestingListFabricScoped()
        : ReadAttribute("list-fabric-scoped")
    {
    }

    ~ReadUnitTestingListFabricScoped() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000002B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        [cluster readAttributeListFabricScopedWithParams:params
                                              completion:^(NSArray * _Nullable value, NSError * _Nullable error) {
                                                  NSLog(@"UnitTesting.ListFabricScoped response %@", [value description]);
                                                  if (error != nil) {
                                                      LogNSError("UnitTesting ListFabricScoped read Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingListFabricScoped : public WriteAttribute {
public:
    WriteUnitTestingListFabricScoped()
        : WriteAttribute("list-fabric-scoped")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "list-fabric-scoped");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingListFabricScoped() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000002B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSArray * _Nonnull value;
        { // Scope for our temporary variables
            auto * array_0 = [NSMutableArray new];
            for (auto & entry_0 : mValue) {
                MTRUnitTestingClusterTestFabricScoped * newElement_0;
                newElement_0 = [MTRUnitTestingClusterTestFabricScoped new];
                newElement_0.fabricSensitiveInt8u = [NSNumber numberWithUnsignedChar:entry_0.fabricSensitiveInt8u];
                if (entry_0.optionalFabricSensitiveInt8u.HasValue()) {
                    newElement_0.optionalFabricSensitiveInt8u =
                        [NSNumber numberWithUnsignedChar:entry_0.optionalFabricSensitiveInt8u.Value()];
                } else {
                    newElement_0.optionalFabricSensitiveInt8u = nil;
                }
                if (entry_0.nullableFabricSensitiveInt8u.IsNull()) {
                    newElement_0.nullableFabricSensitiveInt8u = nil;
                } else {
                    newElement_0.nullableFabricSensitiveInt8u =
                        [NSNumber numberWithUnsignedChar:entry_0.nullableFabricSensitiveInt8u.Value()];
                }
                if (entry_0.nullableOptionalFabricSensitiveInt8u.HasValue()) {
                    if (entry_0.nullableOptionalFabricSensitiveInt8u.Value().IsNull()) {
                        newElement_0.nullableOptionalFabricSensitiveInt8u = nil;
                    } else {
                        newElement_0.nullableOptionalFabricSensitiveInt8u =
                            [NSNumber numberWithUnsignedChar:entry_0.nullableOptionalFabricSensitiveInt8u.Value().Value()];
                    }
                } else {
                    newElement_0.nullableOptionalFabricSensitiveInt8u = nil;
                }
                newElement_0.fabricSensitiveCharString = [[NSString alloc] initWithBytes:entry_0.fabricSensitiveCharString.data()
                                                                                  length:entry_0.fabricSensitiveCharString.size()
                                                                                encoding:NSUTF8StringEncoding];
                newElement_0.fabricSensitiveStruct = [MTRUnitTestingClusterSimpleStruct new];
                newElement_0.fabricSensitiveStruct.a = [NSNumber numberWithUnsignedChar:entry_0.fabricSensitiveStruct.a];
                newElement_0.fabricSensitiveStruct.b = [NSNumber numberWithBool:entry_0.fabricSensitiveStruct.b];
                newElement_0.fabricSensitiveStruct.c =
                    [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.fabricSensitiveStruct.c)];
                newElement_0.fabricSensitiveStruct.d = [NSData dataWithBytes:entry_0.fabricSensitiveStruct.d.data()
                                                                      length:entry_0.fabricSensitiveStruct.d.size()];
                newElement_0.fabricSensitiveStruct.e = [[NSString alloc] initWithBytes:entry_0.fabricSensitiveStruct.e.data()
                                                                                length:entry_0.fabricSensitiveStruct.e.size()
                                                                              encoding:NSUTF8StringEncoding];
                newElement_0.fabricSensitiveStruct.f = [NSNumber numberWithUnsignedChar:entry_0.fabricSensitiveStruct.f.Raw()];
                newElement_0.fabricSensitiveStruct.g = [NSNumber numberWithFloat:entry_0.fabricSensitiveStruct.g];
                newElement_0.fabricSensitiveStruct.h = [NSNumber numberWithDouble:entry_0.fabricSensitiveStruct.h];
                { // Scope for our temporary variables
                    auto * array_2 = [NSMutableArray new];
                    for (auto & entry_2 : entry_0.fabricSensitiveInt8uList) {
                        NSNumber * newElement_2;
                        newElement_2 = [NSNumber numberWithUnsignedChar:entry_2];
                        [array_2 addObject:newElement_2];
                    }
                    newElement_0.fabricSensitiveInt8uList = array_2;
                }
                newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex];
                [array_0 addObject:newElement_0];
            }
            value = array_0;
        }

        [cluster writeAttributeListFabricScopedWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("UnitTesting ListFabricScoped write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::TestFabricScoped::Type> mValue;
    TypedComplexArgument<chip::app::DataModel::List<const chip::app::Clusters::UnitTesting::Structs::TestFabricScoped::Type>>
        mComplex;
};

class SubscribeAttributeUnitTestingListFabricScoped : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingListFabricScoped()
        : SubscribeAttribute("list-fabric-scoped")
    {
    }

    ~SubscribeAttributeUnitTestingListFabricScoped() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000002B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeListFabricScopedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ListFabricScoped response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TimedWriteBoolean
 */
class ReadUnitTestingTimedWriteBoolean : public ReadAttribute {
public:
    ReadUnitTestingTimedWriteBoolean()
        : ReadAttribute("timed-write-boolean")
    {
    }

    ~ReadUnitTestingTimedWriteBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000030) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeTimedWriteBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.TimedWriteBoolean response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting TimedWriteBoolean read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingTimedWriteBoolean : public WriteAttribute {
public:
    WriteUnitTestingTimedWriteBoolean()
        : WriteAttribute("timed-write-boolean")
    {
        AddArgument("attr-name", "timed-write-boolean");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingTimedWriteBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeTimedWriteBooleanWithValue:value
                                                   params:params
                                               completion:^(NSError * _Nullable error) {
                                                   if (error != nil) {
                                                       LogNSError("UnitTesting TimedWriteBoolean write Error", error);
                                                   }
                                                   SetCommandExitStatus(error);
                                               }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeUnitTestingTimedWriteBoolean : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingTimedWriteBoolean()
        : SubscribeAttribute("timed-write-boolean")
    {
    }

    ~SubscribeAttributeUnitTestingTimedWriteBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000030) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeTimedWriteBooleanWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.TimedWriteBoolean response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneralErrorBoolean
 */
class ReadUnitTestingGeneralErrorBoolean : public ReadAttribute {
public:
    ReadUnitTestingGeneralErrorBoolean()
        : ReadAttribute("general-error-boolean")
    {
    }

    ~ReadUnitTestingGeneralErrorBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000031) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeGeneralErrorBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.GeneralErrorBoolean response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting GeneralErrorBoolean read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingGeneralErrorBoolean : public WriteAttribute {
public:
    WriteUnitTestingGeneralErrorBoolean()
        : WriteAttribute("general-error-boolean")
    {
        AddArgument("attr-name", "general-error-boolean");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingGeneralErrorBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeGeneralErrorBooleanWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("UnitTesting GeneralErrorBoolean write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeUnitTestingGeneralErrorBoolean : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingGeneralErrorBoolean()
        : SubscribeAttribute("general-error-boolean")
    {
    }

    ~SubscribeAttributeUnitTestingGeneralErrorBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000031) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneralErrorBooleanWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.GeneralErrorBoolean response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterErrorBoolean
 */
class ReadUnitTestingClusterErrorBoolean : public ReadAttribute {
public:
    ReadUnitTestingClusterErrorBoolean()
        : ReadAttribute("cluster-error-boolean")
    {
    }

    ~ReadUnitTestingClusterErrorBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00000032) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeClusterErrorBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.ClusterErrorBoolean response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting ClusterErrorBoolean read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingClusterErrorBoolean : public WriteAttribute {
public:
    WriteUnitTestingClusterErrorBoolean()
        : WriteAttribute("cluster-error-boolean")
    {
        AddArgument("attr-name", "cluster-error-boolean");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingClusterErrorBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeClusterErrorBooleanWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("UnitTesting ClusterErrorBoolean write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeUnitTestingClusterErrorBoolean : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingClusterErrorBoolean()
        : SubscribeAttribute("cluster-error-boolean")
    {
    }

    ~SubscribeAttributeUnitTestingClusterErrorBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00000032) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterErrorBooleanWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ClusterErrorBoolean response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute Unsupported
 */
class ReadUnitTestingUnsupported : public ReadAttribute {
public:
    ReadUnitTestingUnsupported()
        : ReadAttribute("unsupported")
    {
    }

    ~ReadUnitTestingUnsupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x000000FF) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeUnsupportedWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.Unsupported response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting Unsupported read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingUnsupported : public WriteAttribute {
public:
    WriteUnitTestingUnsupported()
        : WriteAttribute("unsupported")
    {
        AddArgument("attr-name", "unsupported");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingUnsupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x000000FF) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeUnsupportedWithValue:value
                                             params:params
                                         completion:^(NSError * _Nullable error) {
                                             if (error != nil) {
                                                 LogNSError("UnitTesting Unsupported write Error", error);
                                             }
                                             SetCommandExitStatus(error);
                                         }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeUnitTestingUnsupported : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingUnsupported()
        : SubscribeAttribute("unsupported")
    {
    }

    ~SubscribeAttributeUnitTestingUnsupported() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x000000FF) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeUnsupportedWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.Unsupported response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableBoolean
 */
class ReadUnitTestingNullableBoolean : public ReadAttribute {
public:
    ReadUnitTestingNullableBoolean()
        : ReadAttribute("nullable-boolean")
    {
    }

    ~ReadUnitTestingNullableBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004000) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableBooleanWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableBoolean response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableBoolean read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableBoolean : public WriteAttribute {
public:
    WriteUnitTestingNullableBoolean()
        : WriteAttribute("nullable-boolean")
    {
        AddArgument("attr-name", "nullable-boolean");
        AddArgument("attr-value", 0, 1, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithBool:mValue];

        [cluster writeAttributeNullableBooleanWithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("UnitTesting NullableBoolean write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    bool mValue;
};

class SubscribeAttributeUnitTestingNullableBoolean : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableBoolean()
        : SubscribeAttribute("nullable-boolean")
    {
    }

    ~SubscribeAttributeUnitTestingNullableBoolean() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004000) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableBooleanWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableBoolean response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableBitmap8
 */
class ReadUnitTestingNullableBitmap8 : public ReadAttribute {
public:
    ReadUnitTestingNullableBitmap8()
        : ReadAttribute("nullable-bitmap8")
    {
    }

    ~ReadUnitTestingNullableBitmap8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004001) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableBitmap8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableBitmap8 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableBitmap8 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableBitmap8 : public WriteAttribute {
public:
    WriteUnitTestingNullableBitmap8()
        : WriteAttribute("nullable-bitmap8")
    {
        AddArgument("attr-name", "nullable-bitmap8");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableBitmap8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeNullableBitmap8WithValue:value
                                                 params:params
                                             completion:^(NSError * _Nullable error) {
                                                 if (error != nil) {
                                                     LogNSError("UnitTesting NullableBitmap8 write Error", error);
                                                 }
                                                 SetCommandExitStatus(error);
                                             }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingNullableBitmap8 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableBitmap8()
        : SubscribeAttribute("nullable-bitmap8")
    {
    }

    ~SubscribeAttributeUnitTestingNullableBitmap8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004001) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableBitmap8WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableBitmap8 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableBitmap16
 */
class ReadUnitTestingNullableBitmap16 : public ReadAttribute {
public:
    ReadUnitTestingNullableBitmap16()
        : ReadAttribute("nullable-bitmap16")
    {
    }

    ~ReadUnitTestingNullableBitmap16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004002) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableBitmap16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableBitmap16 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableBitmap16 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableBitmap16 : public WriteAttribute {
public:
    WriteUnitTestingNullableBitmap16()
        : WriteAttribute("nullable-bitmap16")
    {
        AddArgument("attr-name", "nullable-bitmap16");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableBitmap16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeNullableBitmap16WithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("UnitTesting NullableBitmap16 write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingNullableBitmap16 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableBitmap16()
        : SubscribeAttribute("nullable-bitmap16")
    {
    }

    ~SubscribeAttributeUnitTestingNullableBitmap16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004002) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableBitmap16WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableBitmap16 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableBitmap32
 */
class ReadUnitTestingNullableBitmap32 : public ReadAttribute {
public:
    ReadUnitTestingNullableBitmap32()
        : ReadAttribute("nullable-bitmap32")
    {
    }

    ~ReadUnitTestingNullableBitmap32() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004003) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableBitmap32WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableBitmap32 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableBitmap32 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableBitmap32 : public WriteAttribute {
public:
    WriteUnitTestingNullableBitmap32()
        : WriteAttribute("nullable-bitmap32")
    {
        AddArgument("attr-name", "nullable-bitmap32");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableBitmap32() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeNullableBitmap32WithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("UnitTesting NullableBitmap32 write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeUnitTestingNullableBitmap32 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableBitmap32()
        : SubscribeAttribute("nullable-bitmap32")
    {
    }

    ~SubscribeAttributeUnitTestingNullableBitmap32() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004003) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableBitmap32WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableBitmap32 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableBitmap64
 */
class ReadUnitTestingNullableBitmap64 : public ReadAttribute {
public:
    ReadUnitTestingNullableBitmap64()
        : ReadAttribute("nullable-bitmap64")
    {
    }

    ~ReadUnitTestingNullableBitmap64() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004004) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableBitmap64WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableBitmap64 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableBitmap64 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableBitmap64 : public WriteAttribute {
public:
    WriteUnitTestingNullableBitmap64()
        : WriteAttribute("nullable-bitmap64")
    {
        AddArgument("attr-name", "nullable-bitmap64");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableBitmap64() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeNullableBitmap64WithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("UnitTesting NullableBitmap64 write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingNullableBitmap64 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableBitmap64()
        : SubscribeAttribute("nullable-bitmap64")
    {
    }

    ~SubscribeAttributeUnitTestingNullableBitmap64() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004004) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableBitmap64WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableBitmap64 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt8u
 */
class ReadUnitTestingNullableInt8u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt8u()
        : ReadAttribute("nullable-int8u")
    {
    }

    ~ReadUnitTestingNullableInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004005) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt8u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt8u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt8u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt8u()
        : WriteAttribute("nullable-int8u")
    {
        AddArgument("attr-name", "nullable-int8u");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeNullableInt8uWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("UnitTesting NullableInt8u write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt8u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt8u()
        : SubscribeAttribute("nullable-int8u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004005) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt8uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt8u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt16u
 */
class ReadUnitTestingNullableInt16u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt16u()
        : ReadAttribute("nullable-int16u")
    {
    }

    ~ReadUnitTestingNullableInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004006) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt16u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt16u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt16u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt16u()
        : WriteAttribute("nullable-int16u")
    {
        AddArgument("attr-name", "nullable-int16u");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeNullableInt16uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt16u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt16u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt16u()
        : SubscribeAttribute("nullable-int16u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004006) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt16uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt16u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt24u
 */
class ReadUnitTestingNullableInt24u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt24u()
        : ReadAttribute("nullable-int24u")
    {
    }

    ~ReadUnitTestingNullableInt24u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004007) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt24uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt24u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt24u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt24u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt24u()
        : WriteAttribute("nullable-int24u")
    {
        AddArgument("attr-name", "nullable-int24u");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt24u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeNullableInt24uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt24u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt24u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt24u()
        : SubscribeAttribute("nullable-int24u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt24u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004007) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt24uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt24u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt32u
 */
class ReadUnitTestingNullableInt32u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt32u()
        : ReadAttribute("nullable-int32u")
    {
    }

    ~ReadUnitTestingNullableInt32u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004008) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt32uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt32u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt32u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt32u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt32u()
        : WriteAttribute("nullable-int32u")
    {
        AddArgument("attr-name", "nullable-int32u");
        AddArgument("attr-value", 0, UINT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt32u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedInt:mValue];

        [cluster writeAttributeNullableInt32uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt32u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint32_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt32u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt32u()
        : SubscribeAttribute("nullable-int32u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt32u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004008) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt32uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt32u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt40u
 */
class ReadUnitTestingNullableInt40u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt40u()
        : ReadAttribute("nullable-int40u")
    {
    }

    ~ReadUnitTestingNullableInt40u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004009) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt40uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt40u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt40u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt40u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt40u()
        : WriteAttribute("nullable-int40u")
    {
        AddArgument("attr-name", "nullable-int40u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt40u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeNullableInt40uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt40u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt40u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt40u()
        : SubscribeAttribute("nullable-int40u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt40u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004009) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt40uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt40u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt48u
 */
class ReadUnitTestingNullableInt48u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt48u()
        : ReadAttribute("nullable-int48u")
    {
    }

    ~ReadUnitTestingNullableInt48u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000400A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt48uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt48u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt48u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt48u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt48u()
        : WriteAttribute("nullable-int48u")
    {
        AddArgument("attr-name", "nullable-int48u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt48u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000400A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeNullableInt48uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt48u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt48u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt48u()
        : SubscribeAttribute("nullable-int48u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt48u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000400A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt48uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt48u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt56u
 */
class ReadUnitTestingNullableInt56u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt56u()
        : ReadAttribute("nullable-int56u")
    {
    }

    ~ReadUnitTestingNullableInt56u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000400B) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt56uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt56u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt56u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt56u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt56u()
        : WriteAttribute("nullable-int56u")
    {
        AddArgument("attr-name", "nullable-int56u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt56u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000400B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeNullableInt56uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt56u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt56u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt56u()
        : SubscribeAttribute("nullable-int56u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt56u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000400B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt56uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt56u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt64u
 */
class ReadUnitTestingNullableInt64u : public ReadAttribute {
public:
    ReadUnitTestingNullableInt64u()
        : ReadAttribute("nullable-int64u")
    {
    }

    ~ReadUnitTestingNullableInt64u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000400C) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt64uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt64u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt64u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt64u : public WriteAttribute {
public:
    WriteUnitTestingNullableInt64u()
        : WriteAttribute("nullable-int64u")
    {
        AddArgument("attr-name", "nullable-int64u");
        AddArgument("attr-value", 0, UINT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt64u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000400C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedLongLong:mValue];

        [cluster writeAttributeNullableInt64uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt64u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt64u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt64u()
        : SubscribeAttribute("nullable-int64u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt64u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000400C) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt64uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt64u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt8s
 */
class ReadUnitTestingNullableInt8s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt8s()
        : ReadAttribute("nullable-int8s")
    {
    }

    ~ReadUnitTestingNullableInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000400D) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt8s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt8s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt8s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt8s()
        : WriteAttribute("nullable-int8s")
    {
        AddArgument("attr-name", "nullable-int8s");
        AddArgument("attr-value", INT8_MIN, INT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000400D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithChar:mValue];

        [cluster writeAttributeNullableInt8sWithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("UnitTesting NullableInt8s write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    int8_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt8s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt8s()
        : SubscribeAttribute("nullable-int8s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000400D) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt8sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt8s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt16s
 */
class ReadUnitTestingNullableInt16s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt16s()
        : ReadAttribute("nullable-int16s")
    {
    }

    ~ReadUnitTestingNullableInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000400E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt16s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt16s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt16s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt16s()
        : WriteAttribute("nullable-int16s")
    {
        AddArgument("attr-name", "nullable-int16s");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000400E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithShort:mValue];

        [cluster writeAttributeNullableInt16sWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt16s write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt16s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt16s()
        : SubscribeAttribute("nullable-int16s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000400E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt16sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt16s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt24s
 */
class ReadUnitTestingNullableInt24s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt24s()
        : ReadAttribute("nullable-int24s")
    {
    }

    ~ReadUnitTestingNullableInt24s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000400F) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt24sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt24s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt24s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt24s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt24s()
        : WriteAttribute("nullable-int24s")
    {
        AddArgument("attr-name", "nullable-int24s");
        AddArgument("attr-value", INT32_MIN, INT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt24s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000400F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithInt:mValue];

        [cluster writeAttributeNullableInt24sWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt24s write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    int32_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt24s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt24s()
        : SubscribeAttribute("nullable-int24s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt24s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000400F) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt24sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt24s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt32s
 */
class ReadUnitTestingNullableInt32s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt32s()
        : ReadAttribute("nullable-int32s")
    {
    }

    ~ReadUnitTestingNullableInt32s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004010) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt32sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt32s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt32s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt32s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt32s()
        : WriteAttribute("nullable-int32s")
    {
        AddArgument("attr-name", "nullable-int32s");
        AddArgument("attr-value", INT32_MIN, INT32_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt32s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithInt:mValue];

        [cluster writeAttributeNullableInt32sWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt32s write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    int32_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt32s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt32s()
        : SubscribeAttribute("nullable-int32s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt32s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004010) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt32sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt32s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt40s
 */
class ReadUnitTestingNullableInt40s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt40s()
        : ReadAttribute("nullable-int40s")
    {
    }

    ~ReadUnitTestingNullableInt40s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004011) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt40sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt40s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt40s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt40s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt40s()
        : WriteAttribute("nullable-int40s")
    {
        AddArgument("attr-name", "nullable-int40s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt40s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeNullableInt40sWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt40s write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt40s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt40s()
        : SubscribeAttribute("nullable-int40s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt40s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004011) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt40sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt40s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt48s
 */
class ReadUnitTestingNullableInt48s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt48s()
        : ReadAttribute("nullable-int48s")
    {
    }

    ~ReadUnitTestingNullableInt48s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004012) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt48sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt48s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt48s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt48s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt48s()
        : WriteAttribute("nullable-int48s")
    {
        AddArgument("attr-name", "nullable-int48s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt48s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeNullableInt48sWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt48s write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt48s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt48s()
        : SubscribeAttribute("nullable-int48s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt48s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004012) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt48sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt48s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt56s
 */
class ReadUnitTestingNullableInt56s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt56s()
        : ReadAttribute("nullable-int56s")
    {
    }

    ~ReadUnitTestingNullableInt56s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004013) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt56sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt56s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt56s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt56s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt56s()
        : WriteAttribute("nullable-int56s")
    {
        AddArgument("attr-name", "nullable-int56s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt56s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeNullableInt56sWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt56s write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt56s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt56s()
        : SubscribeAttribute("nullable-int56s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt56s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004013) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt56sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt56s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableInt64s
 */
class ReadUnitTestingNullableInt64s : public ReadAttribute {
public:
    ReadUnitTestingNullableInt64s()
        : ReadAttribute("nullable-int64s")
    {
    }

    ~ReadUnitTestingNullableInt64s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004014) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableInt64sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableInt64s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableInt64s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableInt64s : public WriteAttribute {
public:
    WriteUnitTestingNullableInt64s()
        : WriteAttribute("nullable-int64s")
    {
        AddArgument("attr-name", "nullable-int64s");
        AddArgument("attr-value", INT64_MIN, INT64_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableInt64s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithLongLong:mValue];

        [cluster writeAttributeNullableInt64sWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableInt64s write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    int64_t mValue;
};

class SubscribeAttributeUnitTestingNullableInt64s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableInt64s()
        : SubscribeAttribute("nullable-int64s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableInt64s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004014) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableInt64sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableInt64s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableEnum8
 */
class ReadUnitTestingNullableEnum8 : public ReadAttribute {
public:
    ReadUnitTestingNullableEnum8()
        : ReadAttribute("nullable-enum8")
    {
    }

    ~ReadUnitTestingNullableEnum8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004015) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableEnum8WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableEnum8 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableEnum8 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableEnum8 : public WriteAttribute {
public:
    WriteUnitTestingNullableEnum8()
        : WriteAttribute("nullable-enum8")
    {
        AddArgument("attr-name", "nullable-enum8");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableEnum8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeNullableEnum8WithValue:value
                                               params:params
                                           completion:^(NSError * _Nullable error) {
                                               if (error != nil) {
                                                   LogNSError("UnitTesting NullableEnum8 write Error", error);
                                               }
                                               SetCommandExitStatus(error);
                                           }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingNullableEnum8 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableEnum8()
        : SubscribeAttribute("nullable-enum8")
    {
    }

    ~SubscribeAttributeUnitTestingNullableEnum8() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004015) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableEnum8WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableEnum8 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableEnum16
 */
class ReadUnitTestingNullableEnum16 : public ReadAttribute {
public:
    ReadUnitTestingNullableEnum16()
        : ReadAttribute("nullable-enum16")
    {
    }

    ~ReadUnitTestingNullableEnum16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004016) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableEnum16WithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableEnum16 response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableEnum16 read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableEnum16 : public WriteAttribute {
public:
    WriteUnitTestingNullableEnum16()
        : WriteAttribute("nullable-enum16")
    {
        AddArgument("attr-name", "nullable-enum16");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableEnum16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster writeAttributeNullableEnum16WithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableEnum16 write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingNullableEnum16 : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableEnum16()
        : SubscribeAttribute("nullable-enum16")
    {
    }

    ~SubscribeAttributeUnitTestingNullableEnum16() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004016) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableEnum16WithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableEnum16 response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableFloatSingle
 */
class ReadUnitTestingNullableFloatSingle : public ReadAttribute {
public:
    ReadUnitTestingNullableFloatSingle()
        : ReadAttribute("nullable-float-single")
    {
    }

    ~ReadUnitTestingNullableFloatSingle() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004017) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableFloatSingleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableFloatSingle response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableFloatSingle read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableFloatSingle : public WriteAttribute {
public:
    WriteUnitTestingNullableFloatSingle()
        : WriteAttribute("nullable-float-single")
    {
        AddArgument("attr-name", "nullable-float-single");
        AddArgument("attr-value", -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableFloatSingle() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithFloat:mValue];

        [cluster writeAttributeNullableFloatSingleWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("UnitTesting NullableFloatSingle write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    float mValue;
};

class SubscribeAttributeUnitTestingNullableFloatSingle : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableFloatSingle()
        : SubscribeAttribute("nullable-float-single")
    {
    }

    ~SubscribeAttributeUnitTestingNullableFloatSingle() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004017) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableFloatSingleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableFloatSingle response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableFloatDouble
 */
class ReadUnitTestingNullableFloatDouble : public ReadAttribute {
public:
    ReadUnitTestingNullableFloatDouble()
        : ReadAttribute("nullable-float-double")
    {
    }

    ~ReadUnitTestingNullableFloatDouble() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004018) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableFloatDoubleWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableFloatDouble response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableFloatDouble read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableFloatDouble : public WriteAttribute {
public:
    WriteUnitTestingNullableFloatDouble()
        : WriteAttribute("nullable-float-double")
    {
        AddArgument("attr-name", "nullable-float-double");
        AddArgument("attr-value", -std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableFloatDouble() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithDouble:mValue];

        [cluster writeAttributeNullableFloatDoubleWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("UnitTesting NullableFloatDouble write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    double mValue;
};

class SubscribeAttributeUnitTestingNullableFloatDouble : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableFloatDouble()
        : SubscribeAttribute("nullable-float-double")
    {
    }

    ~SubscribeAttributeUnitTestingNullableFloatDouble() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004018) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableFloatDoubleWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableFloatDouble response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableOctetString
 */
class ReadUnitTestingNullableOctetString : public ReadAttribute {
public:
    ReadUnitTestingNullableOctetString()
        : ReadAttribute("nullable-octet-string")
    {
    }

    ~ReadUnitTestingNullableOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004019) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableOctetStringWithCompletion:^(NSData * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableOctetString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableOctetString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableOctetString : public WriteAttribute {
public:
    WriteUnitTestingNullableOctetString()
        : WriteAttribute("nullable-octet-string")
    {
        AddArgument("attr-name", "nullable-octet-string");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSData * _Nullable value = [[NSData alloc] initWithBytes:mValue.data() length:mValue.size()];

        [cluster writeAttributeNullableOctetStringWithValue:value
                                                     params:params
                                                 completion:^(NSError * _Nullable error) {
                                                     if (error != nil) {
                                                         LogNSError("UnitTesting NullableOctetString write Error", error);
                                                     }
                                                     SetCommandExitStatus(error);
                                                 }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeUnitTestingNullableOctetString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableOctetString()
        : SubscribeAttribute("nullable-octet-string")
    {
    }

    ~SubscribeAttributeUnitTestingNullableOctetString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004019) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableOctetStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSData * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableOctetString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableCharString
 */
class ReadUnitTestingNullableCharString : public ReadAttribute {
public:
    ReadUnitTestingNullableCharString()
        : ReadAttribute("nullable-char-string")
    {
    }

    ~ReadUnitTestingNullableCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000401E) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableCharStringWithCompletion:^(NSString * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableCharString response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableCharString read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableCharString : public WriteAttribute {
public:
    WriteUnitTestingNullableCharString()
        : WriteAttribute("nullable-char-string")
    {
        AddArgument("attr-name", "nullable-char-string");
        AddArgument("attr-value", &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000401E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSString * _Nullable value = [[NSString alloc] initWithBytes:mValue.data()
                                                              length:mValue.size()
                                                            encoding:NSUTF8StringEncoding];

        [cluster writeAttributeNullableCharStringWithValue:value
                                                    params:params
                                                completion:^(NSError * _Nullable error) {
                                                    if (error != nil) {
                                                        LogNSError("UnitTesting NullableCharString write Error", error);
                                                    }
                                                    SetCommandExitStatus(error);
                                                }];
        return CHIP_NO_ERROR;
    }

private:
    chip::ByteSpan mValue;
};

class SubscribeAttributeUnitTestingNullableCharString : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableCharString()
        : SubscribeAttribute("nullable-char-string")
    {
    }

    ~SubscribeAttributeUnitTestingNullableCharString() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000401E) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableCharStringWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSString * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableCharString response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableEnumAttr
 */
class ReadUnitTestingNullableEnumAttr : public ReadAttribute {
public:
    ReadUnitTestingNullableEnumAttr()
        : ReadAttribute("nullable-enum-attr")
    {
    }

    ~ReadUnitTestingNullableEnumAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004024) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableEnumAttrWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableEnumAttr response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableEnumAttr read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableEnumAttr : public WriteAttribute {
public:
    WriteUnitTestingNullableEnumAttr()
        : WriteAttribute("nullable-enum-attr")
    {
        AddArgument("attr-name", "nullable-enum-attr");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableEnumAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeNullableEnumAttrWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("UnitTesting NullableEnumAttr write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingNullableEnumAttr : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableEnumAttr()
        : SubscribeAttribute("nullable-enum-attr")
    {
    }

    ~SubscribeAttributeUnitTestingNullableEnumAttr() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004024) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableEnumAttrWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableEnumAttr response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableStruct
 */
class ReadUnitTestingNullableStruct : public ReadAttribute {
public:
    ReadUnitTestingNullableStruct()
        : ReadAttribute("nullable-struct")
    {
    }

    ~ReadUnitTestingNullableStruct() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004025) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableStructWithCompletion:^(
            MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableStruct response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableStruct read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableStruct : public WriteAttribute {
public:
    WriteUnitTestingNullableStruct()
        : WriteAttribute("nullable-struct")
        , mComplex(&mValue)
    {
        AddArgument("attr-name", "nullable-struct");
        AddArgument("attr-value", &mComplex);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableStruct() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        MTRUnitTestingClusterSimpleStruct * _Nullable value;
        if (mValue.IsNull()) {
            value = nil;
        } else {
            value = [MTRUnitTestingClusterSimpleStruct new];
            value.a = [NSNumber numberWithUnsignedChar:mValue.Value().a];
            value.b = [NSNumber numberWithBool:mValue.Value().b];
            value.c = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.Value().c)];
            value.d = [NSData dataWithBytes:mValue.Value().d.data() length:mValue.Value().d.size()];
            value.e = [[NSString alloc] initWithBytes:mValue.Value().e.data()
                                               length:mValue.Value().e.size()
                                             encoding:NSUTF8StringEncoding];
            value.f = [NSNumber numberWithUnsignedChar:mValue.Value().f.Raw()];
            value.g = [NSNumber numberWithFloat:mValue.Value().g];
            value.h = [NSNumber numberWithDouble:mValue.Value().h];
        }

        [cluster writeAttributeNullableStructWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting NullableStruct write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    chip::app::DataModel::Nullable<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type> mValue;
    TypedComplexArgument<chip::app::DataModel::Nullable<chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type>> mComplex;
};

class SubscribeAttributeUnitTestingNullableStruct : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableStruct()
        : SubscribeAttribute("nullable-struct")
    {
    }

    ~SubscribeAttributeUnitTestingNullableStruct() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004025) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableStructWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(MTRUnitTestingClusterSimpleStruct * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableStruct response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableRangeRestrictedInt8u
 */
class ReadUnitTestingNullableRangeRestrictedInt8u : public ReadAttribute {
public:
    ReadUnitTestingNullableRangeRestrictedInt8u()
        : ReadAttribute("nullable-range-restricted-int8u")
    {
    }

    ~ReadUnitTestingNullableRangeRestrictedInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004026) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableRangeRestrictedInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableRangeRestrictedInt8u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableRangeRestrictedInt8u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableRangeRestrictedInt8u : public WriteAttribute {
public:
    WriteUnitTestingNullableRangeRestrictedInt8u()
        : WriteAttribute("nullable-range-restricted-int8u")
    {
        AddArgument("attr-name", "nullable-range-restricted-int8u");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableRangeRestrictedInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004026) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeNullableRangeRestrictedInt8uWithValue:value
                                                              params:params
                                                          completion:^(NSError * _Nullable error) {
                                                              if (error != nil) {
                                                                  LogNSError("UnitTesting NullableRangeRestrictedInt8u write Error",
                                                                      error);
                                                              }
                                                              SetCommandExitStatus(error);
                                                          }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingNullableRangeRestrictedInt8u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableRangeRestrictedInt8u()
        : SubscribeAttribute("nullable-range-restricted-int8u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableRangeRestrictedInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004026) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableRangeRestrictedInt8uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableRangeRestrictedInt8u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableRangeRestrictedInt8s
 */
class ReadUnitTestingNullableRangeRestrictedInt8s : public ReadAttribute {
public:
    ReadUnitTestingNullableRangeRestrictedInt8s()
        : ReadAttribute("nullable-range-restricted-int8s")
    {
    }

    ~ReadUnitTestingNullableRangeRestrictedInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004027) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableRangeRestrictedInt8sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableRangeRestrictedInt8s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableRangeRestrictedInt8s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableRangeRestrictedInt8s : public WriteAttribute {
public:
    WriteUnitTestingNullableRangeRestrictedInt8s()
        : WriteAttribute("nullable-range-restricted-int8s")
    {
        AddArgument("attr-name", "nullable-range-restricted-int8s");
        AddArgument("attr-value", INT8_MIN, INT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableRangeRestrictedInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004027) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithChar:mValue];

        [cluster writeAttributeNullableRangeRestrictedInt8sWithValue:value
                                                              params:params
                                                          completion:^(NSError * _Nullable error) {
                                                              if (error != nil) {
                                                                  LogNSError("UnitTesting NullableRangeRestrictedInt8s write Error",
                                                                      error);
                                                              }
                                                              SetCommandExitStatus(error);
                                                          }];
        return CHIP_NO_ERROR;
    }

private:
    int8_t mValue;
};

class SubscribeAttributeUnitTestingNullableRangeRestrictedInt8s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableRangeRestrictedInt8s()
        : SubscribeAttribute("nullable-range-restricted-int8s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableRangeRestrictedInt8s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004027) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableRangeRestrictedInt8sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableRangeRestrictedInt8s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableRangeRestrictedInt16u
 */
class ReadUnitTestingNullableRangeRestrictedInt16u : public ReadAttribute {
public:
    ReadUnitTestingNullableRangeRestrictedInt16u()
        : ReadAttribute("nullable-range-restricted-int16u")
    {
    }

    ~ReadUnitTestingNullableRangeRestrictedInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004028) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableRangeRestrictedInt16uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableRangeRestrictedInt16u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableRangeRestrictedInt16u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableRangeRestrictedInt16u : public WriteAttribute {
public:
    WriteUnitTestingNullableRangeRestrictedInt16u()
        : WriteAttribute("nullable-range-restricted-int16u")
    {
        AddArgument("attr-name", "nullable-range-restricted-int16u");
        AddArgument("attr-value", 0, UINT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableRangeRestrictedInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithUnsignedShort:mValue];

        [cluster
            writeAttributeNullableRangeRestrictedInt16uWithValue:value
                                                          params:params
                                                      completion:^(NSError * _Nullable error) {
                                                          if (error != nil) {
                                                              LogNSError(
                                                                  "UnitTesting NullableRangeRestrictedInt16u write Error", error);
                                                          }
                                                          SetCommandExitStatus(error);
                                                      }];
        return CHIP_NO_ERROR;
    }

private:
    uint16_t mValue;
};

class SubscribeAttributeUnitTestingNullableRangeRestrictedInt16u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableRangeRestrictedInt16u()
        : SubscribeAttribute("nullable-range-restricted-int16u")
    {
    }

    ~SubscribeAttributeUnitTestingNullableRangeRestrictedInt16u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004028) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableRangeRestrictedInt16uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableRangeRestrictedInt16u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute NullableRangeRestrictedInt16s
 */
class ReadUnitTestingNullableRangeRestrictedInt16s : public ReadAttribute {
public:
    ReadUnitTestingNullableRangeRestrictedInt16s()
        : ReadAttribute("nullable-range-restricted-int16s")
    {
    }

    ~ReadUnitTestingNullableRangeRestrictedInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x00004029) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeNullableRangeRestrictedInt16sWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.NullableRangeRestrictedInt16s response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting NullableRangeRestrictedInt16s read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingNullableRangeRestrictedInt16s : public WriteAttribute {
public:
    WriteUnitTestingNullableRangeRestrictedInt16s()
        : WriteAttribute("nullable-range-restricted-int16s")
    {
        AddArgument("attr-name", "nullable-range-restricted-int16s");
        AddArgument("attr-value", INT16_MIN, INT16_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingNullableRangeRestrictedInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x00004029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nullable value = [NSNumber numberWithShort:mValue];

        [cluster
            writeAttributeNullableRangeRestrictedInt16sWithValue:value
                                                          params:params
                                                      completion:^(NSError * _Nullable error) {
                                                          if (error != nil) {
                                                              LogNSError(
                                                                  "UnitTesting NullableRangeRestrictedInt16s write Error", error);
                                                          }
                                                          SetCommandExitStatus(error);
                                                      }];
        return CHIP_NO_ERROR;
    }

private:
    int16_t mValue;
};

class SubscribeAttributeUnitTestingNullableRangeRestrictedInt16s : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingNullableRangeRestrictedInt16s()
        : SubscribeAttribute("nullable-range-restricted-int16s")
    {
    }

    ~SubscribeAttributeUnitTestingNullableRangeRestrictedInt16s() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x00004029) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeNullableRangeRestrictedInt16sWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.NullableRangeRestrictedInt16s response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute WriteOnlyInt8u
 */
class ReadUnitTestingWriteOnlyInt8u : public ReadAttribute {
public:
    ReadUnitTestingWriteOnlyInt8u()
        : ReadAttribute("write-only-int8u")
    {
    }

    ~ReadUnitTestingWriteOnlyInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000402A) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeWriteOnlyInt8uWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.WriteOnlyInt8u response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting WriteOnlyInt8u read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class WriteUnitTestingWriteOnlyInt8u : public WriteAttribute {
public:
    WriteUnitTestingWriteOnlyInt8u()
        : WriteAttribute("write-only-int8u")
    {
        AddArgument("attr-name", "write-only-int8u");
        AddArgument("attr-value", 0, UINT8_MAX, &mValue);
        WriteAttribute::AddArguments();
    }

    ~WriteUnitTestingWriteOnlyInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) WriteAttribute (0x0000402A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout
            = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue];

        [cluster writeAttributeWriteOnlyInt8uWithValue:value
                                                params:params
                                            completion:^(NSError * _Nullable error) {
                                                if (error != nil) {
                                                    LogNSError("UnitTesting WriteOnlyInt8u write Error", error);
                                                }
                                                SetCommandExitStatus(error);
                                            }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeUnitTestingWriteOnlyInt8u : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingWriteOnlyInt8u()
        : SubscribeAttribute("write-only-int8u")
    {
    }

    ~SubscribeAttributeUnitTestingWriteOnlyInt8u() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000402A) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeWriteOnlyInt8uWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.WriteOnlyInt8u response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute GeneratedCommandList
 */
class ReadUnitTestingGeneratedCommandList : public ReadAttribute {
public:
    ReadUnitTestingGeneratedCommandList()
        : ReadAttribute("generated-command-list")
    {
    }

    ~ReadUnitTestingGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000FFF8) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.GeneratedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting GeneratedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitTestingGeneratedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingGeneratedCommandList()
        : SubscribeAttribute("generated-command-list")
    {
    }

    ~SubscribeAttributeUnitTestingGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeGeneratedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AcceptedCommandList
 */
class ReadUnitTestingAcceptedCommandList : public ReadAttribute {
public:
    ReadUnitTestingAcceptedCommandList()
        : ReadAttribute("accepted-command-list")
    {
    }

    ~ReadUnitTestingAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000FFF9) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.AcceptedCommandList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting AcceptedCommandList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitTestingAcceptedCommandList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingAcceptedCommandList()
        : SubscribeAttribute("accepted-command-list")
    {
    }

    ~SubscribeAttributeUnitTestingAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAcceptedCommandListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute AttributeList
 */
class ReadUnitTestingAttributeList : public ReadAttribute {
public:
    ReadUnitTestingAttributeList()
        : ReadAttribute("attribute-list")
    {
    }

    ~ReadUnitTestingAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000FFFB) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.AttributeList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting AttributeList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitTestingAttributeList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingAttributeList()
        : SubscribeAttribute("attribute-list")
    {
    }

    ~SubscribeAttributeUnitTestingAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeAttributeListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute FeatureMap
 */
class ReadUnitTestingFeatureMap : public ReadAttribute {
public:
    ReadUnitTestingFeatureMap()
        : ReadAttribute("feature-map")
    {
    }

    ~ReadUnitTestingFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000FFFC) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.FeatureMap response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting FeatureMap read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitTestingFeatureMap : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingFeatureMap()
        : SubscribeAttribute("feature-map")
    {
    }

    ~SubscribeAttributeUnitTestingFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeFeatureMapWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ClusterRevision
 */
class ReadUnitTestingClusterRevision : public ReadAttribute {
public:
    ReadUnitTestingClusterRevision()
        : ReadAttribute("cluster-revision")
    {
    }

    ~ReadUnitTestingClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReadAttribute (0x0000FFFD) on endpoint %u", endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.ClusterRevision response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting ClusterRevision read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitTestingClusterRevision : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingClusterRevision()
        : SubscribeAttribute("cluster-revision")
    {
    }

    ~SubscribeAttributeUnitTestingClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device
                                                                       endpointID:@(endpointId)
                                                                            queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
            params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
            params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
            params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribeAttributeClusterRevisionWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Register all Clusters commands                                               |
\*----------------------------------------------------------------------------*/
void registerClusterIdentify(Commands & commands)
{
    using namespace chip::app::Clusters::Identify;

    const char * clusterName = "Identify";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<IdentifyIdentify>(), //
        make_unique<IdentifyTriggerEffect>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadIdentifyIdentifyTime>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteIdentifyIdentifyTime>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeIdentifyIdentifyTime>(), //
        make_unique<ReadIdentifyIdentifyType>(), //
        make_unique<SubscribeAttributeIdentifyIdentifyType>(), //
        make_unique<ReadIdentifyGeneratedCommandList>(), //
        make_unique<SubscribeAttributeIdentifyGeneratedCommandList>(), //
        make_unique<ReadIdentifyAcceptedCommandList>(), //
        make_unique<SubscribeAttributeIdentifyAcceptedCommandList>(), //
        make_unique<ReadIdentifyAttributeList>(), //
        make_unique<SubscribeAttributeIdentifyAttributeList>(), //
        make_unique<ReadIdentifyFeatureMap>(), //
        make_unique<SubscribeAttributeIdentifyFeatureMap>(), //
        make_unique<ReadIdentifyClusterRevision>(), //
        make_unique<SubscribeAttributeIdentifyClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterGroups(Commands & commands)
{
    using namespace chip::app::Clusters::Groups;

    const char * clusterName = "Groups";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<GroupsAddGroup>(), //
        make_unique<GroupsViewGroup>(), //
        make_unique<GroupsGetGroupMembership>(), //
        make_unique<GroupsRemoveGroup>(), //
        make_unique<GroupsRemoveAllGroups>(), //
        make_unique<GroupsAddGroupIfIdentifying>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadGroupsNameSupport>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeGroupsNameSupport>(), //
        make_unique<ReadGroupsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeGroupsGeneratedCommandList>(), //
        make_unique<ReadGroupsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeGroupsAcceptedCommandList>(), //
        make_unique<ReadGroupsAttributeList>(), //
        make_unique<SubscribeAttributeGroupsAttributeList>(), //
        make_unique<ReadGroupsFeatureMap>(), //
        make_unique<SubscribeAttributeGroupsFeatureMap>(), //
        make_unique<ReadGroupsClusterRevision>(), //
        make_unique<SubscribeAttributeGroupsClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterScenes(Commands & commands)
{
    using namespace chip::app::Clusters::Scenes;

    const char * clusterName = "Scenes";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ScenesAddScene>(), //
        make_unique<ScenesViewScene>(), //
        make_unique<ScenesRemoveScene>(), //
        make_unique<ScenesRemoveAllScenes>(), //
        make_unique<ScenesStoreScene>(), //
        make_unique<ScenesRecallScene>(), //
        make_unique<ScenesGetSceneMembership>(), //
        make_unique<ScenesEnhancedAddScene>(), //
        make_unique<ScenesEnhancedViewScene>(), //
        make_unique<ScenesCopyScene>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadScenesSceneCount>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeScenesSceneCount>(), //
        make_unique<ReadScenesCurrentScene>(), //
        make_unique<SubscribeAttributeScenesCurrentScene>(), //
        make_unique<ReadScenesCurrentGroup>(), //
        make_unique<SubscribeAttributeScenesCurrentGroup>(), //
        make_unique<ReadScenesSceneValid>(), //
        make_unique<SubscribeAttributeScenesSceneValid>(), //
        make_unique<ReadScenesNameSupport>(), //
        make_unique<SubscribeAttributeScenesNameSupport>(), //
        make_unique<ReadScenesLastConfiguredBy>(), //
        make_unique<SubscribeAttributeScenesLastConfiguredBy>(), //
        make_unique<ReadScenesGeneratedCommandList>(), //
        make_unique<SubscribeAttributeScenesGeneratedCommandList>(), //
        make_unique<ReadScenesAcceptedCommandList>(), //
        make_unique<SubscribeAttributeScenesAcceptedCommandList>(), //
        make_unique<ReadScenesAttributeList>(), //
        make_unique<SubscribeAttributeScenesAttributeList>(), //
        make_unique<ReadScenesFeatureMap>(), //
        make_unique<SubscribeAttributeScenesFeatureMap>(), //
        make_unique<ReadScenesClusterRevision>(), //
        make_unique<SubscribeAttributeScenesClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterOnOff(Commands & commands)
{
    using namespace chip::app::Clusters::OnOff;

    const char * clusterName = "OnOff";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<OnOffOff>(), //
        make_unique<OnOffOn>(), //
        make_unique<OnOffToggle>(), //
        make_unique<OnOffOffWithEffect>(), //
        make_unique<OnOffOnWithRecallGlobalScene>(), //
        make_unique<OnOffOnWithTimedOff>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadOnOffOnOff>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeOnOffOnOff>(), //
        make_unique<ReadOnOffGlobalSceneControl>(), //
        make_unique<SubscribeAttributeOnOffGlobalSceneControl>(), //
        make_unique<ReadOnOffOnTime>(), //
        make_unique<WriteOnOffOnTime>(), //
        make_unique<SubscribeAttributeOnOffOnTime>(), //
        make_unique<ReadOnOffOffWaitTime>(), //
        make_unique<WriteOnOffOffWaitTime>(), //
        make_unique<SubscribeAttributeOnOffOffWaitTime>(), //
        make_unique<ReadOnOffStartUpOnOff>(), //
        make_unique<WriteOnOffStartUpOnOff>(), //
        make_unique<SubscribeAttributeOnOffStartUpOnOff>(), //
        make_unique<ReadOnOffGeneratedCommandList>(), //
        make_unique<SubscribeAttributeOnOffGeneratedCommandList>(), //
        make_unique<ReadOnOffAcceptedCommandList>(), //
        make_unique<SubscribeAttributeOnOffAcceptedCommandList>(), //
        make_unique<ReadOnOffAttributeList>(), //
        make_unique<SubscribeAttributeOnOffAttributeList>(), //
        make_unique<ReadOnOffFeatureMap>(), //
        make_unique<SubscribeAttributeOnOffFeatureMap>(), //
        make_unique<ReadOnOffClusterRevision>(), //
        make_unique<SubscribeAttributeOnOffClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterOnOffSwitchConfiguration(Commands & commands)
{
    using namespace chip::app::Clusters::OnOffSwitchConfiguration;

    const char * clusterName = "OnOffSwitchConfiguration";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadOnOffSwitchConfigurationSwitchType>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationSwitchType>(), //
        make_unique<ReadOnOffSwitchConfigurationSwitchActions>(), //
        make_unique<WriteOnOffSwitchConfigurationSwitchActions>(), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationSwitchActions>(), //
        make_unique<ReadOnOffSwitchConfigurationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationGeneratedCommandList>(), //
        make_unique<ReadOnOffSwitchConfigurationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationAcceptedCommandList>(), //
        make_unique<ReadOnOffSwitchConfigurationAttributeList>(), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationAttributeList>(), //
        make_unique<ReadOnOffSwitchConfigurationFeatureMap>(), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationFeatureMap>(), //
        make_unique<ReadOnOffSwitchConfigurationClusterRevision>(), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterLevelControl(Commands & commands)
{
    using namespace chip::app::Clusters::LevelControl;

    const char * clusterName = "LevelControl";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<LevelControlMoveToLevel>(), //
        make_unique<LevelControlMove>(), //
        make_unique<LevelControlStep>(), //
        make_unique<LevelControlStop>(), //
        make_unique<LevelControlMoveToLevelWithOnOff>(), //
        make_unique<LevelControlMoveWithOnOff>(), //
        make_unique<LevelControlStepWithOnOff>(), //
        make_unique<LevelControlStopWithOnOff>(), //
        make_unique<LevelControlMoveToClosestFrequency>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadLevelControlCurrentLevel>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeLevelControlCurrentLevel>(), //
        make_unique<ReadLevelControlRemainingTime>(), //
        make_unique<SubscribeAttributeLevelControlRemainingTime>(), //
        make_unique<ReadLevelControlMinLevel>(), //
        make_unique<SubscribeAttributeLevelControlMinLevel>(), //
        make_unique<ReadLevelControlMaxLevel>(), //
        make_unique<SubscribeAttributeLevelControlMaxLevel>(), //
        make_unique<ReadLevelControlCurrentFrequency>(), //
        make_unique<SubscribeAttributeLevelControlCurrentFrequency>(), //
        make_unique<ReadLevelControlMinFrequency>(), //
        make_unique<SubscribeAttributeLevelControlMinFrequency>(), //
        make_unique<ReadLevelControlMaxFrequency>(), //
        make_unique<SubscribeAttributeLevelControlMaxFrequency>(), //
        make_unique<ReadLevelControlOptions>(), //
        make_unique<WriteLevelControlOptions>(), //
        make_unique<SubscribeAttributeLevelControlOptions>(), //
        make_unique<ReadLevelControlOnOffTransitionTime>(), //
        make_unique<WriteLevelControlOnOffTransitionTime>(), //
        make_unique<SubscribeAttributeLevelControlOnOffTransitionTime>(), //
        make_unique<ReadLevelControlOnLevel>(), //
        make_unique<WriteLevelControlOnLevel>(), //
        make_unique<SubscribeAttributeLevelControlOnLevel>(), //
        make_unique<ReadLevelControlOnTransitionTime>(), //
        make_unique<WriteLevelControlOnTransitionTime>(), //
        make_unique<SubscribeAttributeLevelControlOnTransitionTime>(), //
        make_unique<ReadLevelControlOffTransitionTime>(), //
        make_unique<WriteLevelControlOffTransitionTime>(), //
        make_unique<SubscribeAttributeLevelControlOffTransitionTime>(), //
        make_unique<ReadLevelControlDefaultMoveRate>(), //
        make_unique<WriteLevelControlDefaultMoveRate>(), //
        make_unique<SubscribeAttributeLevelControlDefaultMoveRate>(), //
        make_unique<ReadLevelControlStartUpCurrentLevel>(), //
        make_unique<WriteLevelControlStartUpCurrentLevel>(), //
        make_unique<SubscribeAttributeLevelControlStartUpCurrentLevel>(), //
        make_unique<ReadLevelControlGeneratedCommandList>(), //
        make_unique<SubscribeAttributeLevelControlGeneratedCommandList>(), //
        make_unique<ReadLevelControlAcceptedCommandList>(), //
        make_unique<SubscribeAttributeLevelControlAcceptedCommandList>(), //
        make_unique<ReadLevelControlAttributeList>(), //
        make_unique<SubscribeAttributeLevelControlAttributeList>(), //
        make_unique<ReadLevelControlFeatureMap>(), //
        make_unique<SubscribeAttributeLevelControlFeatureMap>(), //
        make_unique<ReadLevelControlClusterRevision>(), //
        make_unique<SubscribeAttributeLevelControlClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterBinaryInputBasic(Commands & commands)
{
    using namespace chip::app::Clusters::BinaryInputBasic;

    const char * clusterName = "BinaryInputBasic";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadBinaryInputBasicActiveText>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteBinaryInputBasicActiveText>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeBinaryInputBasicActiveText>(), //
        make_unique<ReadBinaryInputBasicDescription>(), //
        make_unique<WriteBinaryInputBasicDescription>(), //
        make_unique<SubscribeAttributeBinaryInputBasicDescription>(), //
        make_unique<ReadBinaryInputBasicInactiveText>(), //
        make_unique<WriteBinaryInputBasicInactiveText>(), //
        make_unique<SubscribeAttributeBinaryInputBasicInactiveText>(), //
        make_unique<ReadBinaryInputBasicOutOfService>(), //
        make_unique<WriteBinaryInputBasicOutOfService>(), //
        make_unique<SubscribeAttributeBinaryInputBasicOutOfService>(), //
        make_unique<ReadBinaryInputBasicPolarity>(), //
        make_unique<SubscribeAttributeBinaryInputBasicPolarity>(), //
        make_unique<ReadBinaryInputBasicPresentValue>(), //
        make_unique<WriteBinaryInputBasicPresentValue>(), //
        make_unique<SubscribeAttributeBinaryInputBasicPresentValue>(), //
        make_unique<ReadBinaryInputBasicReliability>(), //
        make_unique<WriteBinaryInputBasicReliability>(), //
        make_unique<SubscribeAttributeBinaryInputBasicReliability>(), //
        make_unique<ReadBinaryInputBasicStatusFlags>(), //
        make_unique<SubscribeAttributeBinaryInputBasicStatusFlags>(), //
        make_unique<ReadBinaryInputBasicApplicationType>(), //
        make_unique<SubscribeAttributeBinaryInputBasicApplicationType>(), //
        make_unique<ReadBinaryInputBasicGeneratedCommandList>(), //
        make_unique<SubscribeAttributeBinaryInputBasicGeneratedCommandList>(), //
        make_unique<ReadBinaryInputBasicAcceptedCommandList>(), //
        make_unique<SubscribeAttributeBinaryInputBasicAcceptedCommandList>(), //
        make_unique<ReadBinaryInputBasicAttributeList>(), //
        make_unique<SubscribeAttributeBinaryInputBasicAttributeList>(), //
        make_unique<ReadBinaryInputBasicFeatureMap>(), //
        make_unique<SubscribeAttributeBinaryInputBasicFeatureMap>(), //
        make_unique<ReadBinaryInputBasicClusterRevision>(), //
        make_unique<SubscribeAttributeBinaryInputBasicClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterDescriptor(Commands & commands)
{
    using namespace chip::app::Clusters::Descriptor;

    const char * clusterName = "Descriptor";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadDescriptorDeviceTypeList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeDescriptorDeviceTypeList>(), //
        make_unique<ReadDescriptorServerList>(), //
        make_unique<SubscribeAttributeDescriptorServerList>(), //
        make_unique<ReadDescriptorClientList>(), //
        make_unique<SubscribeAttributeDescriptorClientList>(), //
        make_unique<ReadDescriptorPartsList>(), //
        make_unique<SubscribeAttributeDescriptorPartsList>(), //
        make_unique<ReadDescriptorGeneratedCommandList>(), //
        make_unique<SubscribeAttributeDescriptorGeneratedCommandList>(), //
        make_unique<ReadDescriptorAcceptedCommandList>(), //
        make_unique<SubscribeAttributeDescriptorAcceptedCommandList>(), //
        make_unique<ReadDescriptorAttributeList>(), //
        make_unique<SubscribeAttributeDescriptorAttributeList>(), //
        make_unique<ReadDescriptorFeatureMap>(), //
        make_unique<SubscribeAttributeDescriptorFeatureMap>(), //
        make_unique<ReadDescriptorClusterRevision>(), //
        make_unique<SubscribeAttributeDescriptorClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterBinding(Commands & commands)
{
    using namespace chip::app::Clusters::Binding;

    const char * clusterName = "Binding";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadBindingBinding>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteBindingBinding>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeBindingBinding>(), //
        make_unique<ReadBindingGeneratedCommandList>(), //
        make_unique<SubscribeAttributeBindingGeneratedCommandList>(), //
        make_unique<ReadBindingAcceptedCommandList>(), //
        make_unique<SubscribeAttributeBindingAcceptedCommandList>(), //
        make_unique<ReadBindingAttributeList>(), //
        make_unique<SubscribeAttributeBindingAttributeList>(), //
        make_unique<ReadBindingFeatureMap>(), //
        make_unique<SubscribeAttributeBindingFeatureMap>(), //
        make_unique<ReadBindingClusterRevision>(), //
        make_unique<SubscribeAttributeBindingClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterAccessControl(Commands & commands)
{
    using namespace chip::app::Clusters::AccessControl;

    const char * clusterName = "AccessControl";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadAccessControlAcl>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteAccessControlAcl>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeAccessControlAcl>(), //
        make_unique<ReadAccessControlExtension>(), //
        make_unique<WriteAccessControlExtension>(), //
        make_unique<SubscribeAttributeAccessControlExtension>(), //
        make_unique<ReadAccessControlSubjectsPerAccessControlEntry>(), //
        make_unique<SubscribeAttributeAccessControlSubjectsPerAccessControlEntry>(), //
        make_unique<ReadAccessControlTargetsPerAccessControlEntry>(), //
        make_unique<SubscribeAttributeAccessControlTargetsPerAccessControlEntry>(), //
        make_unique<ReadAccessControlAccessControlEntriesPerFabric>(), //
        make_unique<SubscribeAttributeAccessControlAccessControlEntriesPerFabric>(), //
        make_unique<ReadAccessControlGeneratedCommandList>(), //
        make_unique<SubscribeAttributeAccessControlGeneratedCommandList>(), //
        make_unique<ReadAccessControlAcceptedCommandList>(), //
        make_unique<SubscribeAttributeAccessControlAcceptedCommandList>(), //
        make_unique<ReadAccessControlAttributeList>(), //
        make_unique<SubscribeAttributeAccessControlAttributeList>(), //
        make_unique<ReadAccessControlFeatureMap>(), //
        make_unique<SubscribeAttributeAccessControlFeatureMap>(), //
        make_unique<ReadAccessControlClusterRevision>(), //
        make_unique<SubscribeAttributeAccessControlClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterActions(Commands & commands)
{
    using namespace chip::app::Clusters::Actions;

    const char * clusterName = "Actions";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ActionsInstantAction>(), //
        make_unique<ActionsInstantActionWithTransition>(), //
        make_unique<ActionsStartAction>(), //
        make_unique<ActionsStartActionWithDuration>(), //
        make_unique<ActionsStopAction>(), //
        make_unique<ActionsPauseAction>(), //
        make_unique<ActionsPauseActionWithDuration>(), //
        make_unique<ActionsResumeAction>(), //
        make_unique<ActionsEnableAction>(), //
        make_unique<ActionsEnableActionWithDuration>(), //
        make_unique<ActionsDisableAction>(), //
        make_unique<ActionsDisableActionWithDuration>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadActionsActionList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeActionsActionList>(), //
        make_unique<ReadActionsEndpointLists>(), //
        make_unique<SubscribeAttributeActionsEndpointLists>(), //
        make_unique<ReadActionsSetupURL>(), //
        make_unique<SubscribeAttributeActionsSetupURL>(), //
        make_unique<ReadActionsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeActionsGeneratedCommandList>(), //
        make_unique<ReadActionsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeActionsAcceptedCommandList>(), //
        make_unique<ReadActionsAttributeList>(), //
        make_unique<SubscribeAttributeActionsAttributeList>(), //
        make_unique<ReadActionsFeatureMap>(), //
        make_unique<SubscribeAttributeActionsFeatureMap>(), //
        make_unique<ReadActionsClusterRevision>(), //
        make_unique<SubscribeAttributeActionsClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterBasicInformation(Commands & commands)
{
    using namespace chip::app::Clusters::BasicInformation;

    const char * clusterName = "BasicInformation";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadBasicInformationDataModelRevision>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeBasicInformationDataModelRevision>(), //
        make_unique<ReadBasicInformationVendorName>(), //
        make_unique<SubscribeAttributeBasicInformationVendorName>(), //
        make_unique<ReadBasicInformationVendorID>(), //
        make_unique<SubscribeAttributeBasicInformationVendorID>(), //
        make_unique<ReadBasicInformationProductName>(), //
        make_unique<SubscribeAttributeBasicInformationProductName>(), //
        make_unique<ReadBasicInformationProductID>(), //
        make_unique<SubscribeAttributeBasicInformationProductID>(), //
        make_unique<ReadBasicInformationNodeLabel>(), //
        make_unique<WriteBasicInformationNodeLabel>(), //
        make_unique<SubscribeAttributeBasicInformationNodeLabel>(), //
        make_unique<ReadBasicInformationLocation>(), //
        make_unique<WriteBasicInformationLocation>(), //
        make_unique<SubscribeAttributeBasicInformationLocation>(), //
        make_unique<ReadBasicInformationHardwareVersion>(), //
        make_unique<SubscribeAttributeBasicInformationHardwareVersion>(), //
        make_unique<ReadBasicInformationHardwareVersionString>(), //
        make_unique<SubscribeAttributeBasicInformationHardwareVersionString>(), //
        make_unique<ReadBasicInformationSoftwareVersion>(), //
        make_unique<SubscribeAttributeBasicInformationSoftwareVersion>(), //
        make_unique<ReadBasicInformationSoftwareVersionString>(), //
        make_unique<SubscribeAttributeBasicInformationSoftwareVersionString>(), //
        make_unique<ReadBasicInformationManufacturingDate>(), //
        make_unique<SubscribeAttributeBasicInformationManufacturingDate>(), //
        make_unique<ReadBasicInformationPartNumber>(), //
        make_unique<SubscribeAttributeBasicInformationPartNumber>(), //
        make_unique<ReadBasicInformationProductURL>(), //
        make_unique<SubscribeAttributeBasicInformationProductURL>(), //
        make_unique<ReadBasicInformationProductLabel>(), //
        make_unique<SubscribeAttributeBasicInformationProductLabel>(), //
        make_unique<ReadBasicInformationSerialNumber>(), //
        make_unique<SubscribeAttributeBasicInformationSerialNumber>(), //
        make_unique<ReadBasicInformationLocalConfigDisabled>(), //
        make_unique<WriteBasicInformationLocalConfigDisabled>(), //
        make_unique<SubscribeAttributeBasicInformationLocalConfigDisabled>(), //
        make_unique<ReadBasicInformationReachable>(), //
        make_unique<SubscribeAttributeBasicInformationReachable>(), //
        make_unique<ReadBasicInformationUniqueID>(), //
        make_unique<SubscribeAttributeBasicInformationUniqueID>(), //
        make_unique<ReadBasicInformationCapabilityMinima>(), //
        make_unique<SubscribeAttributeBasicInformationCapabilityMinima>(), //
        make_unique<ReadBasicInformationProductAppearance>(), //
        make_unique<SubscribeAttributeBasicInformationProductAppearance>(), //
        make_unique<ReadBasicInformationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeBasicInformationGeneratedCommandList>(), //
        make_unique<ReadBasicInformationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeBasicInformationAcceptedCommandList>(), //
        make_unique<ReadBasicInformationAttributeList>(), //
        make_unique<SubscribeAttributeBasicInformationAttributeList>(), //
        make_unique<ReadBasicInformationFeatureMap>(), //
        make_unique<SubscribeAttributeBasicInformationFeatureMap>(), //
        make_unique<ReadBasicInformationClusterRevision>(), //
        make_unique<SubscribeAttributeBasicInformationClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterOtaSoftwareUpdateProvider(Commands & commands)
{
    using namespace chip::app::Clusters::OtaSoftwareUpdateProvider;

    const char * clusterName = "OtaSoftwareUpdateProvider";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<OtaSoftwareUpdateProviderQueryImage>(), //
        make_unique<OtaSoftwareUpdateProviderApplyUpdateRequest>(), //
        make_unique<OtaSoftwareUpdateProviderNotifyUpdateApplied>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadOtaSoftwareUpdateProviderGeneratedCommandList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateProviderGeneratedCommandList>(), //
        make_unique<ReadOtaSoftwareUpdateProviderAcceptedCommandList>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateProviderAcceptedCommandList>(), //
        make_unique<ReadOtaSoftwareUpdateProviderAttributeList>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateProviderAttributeList>(), //
        make_unique<ReadOtaSoftwareUpdateProviderFeatureMap>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateProviderFeatureMap>(), //
        make_unique<ReadOtaSoftwareUpdateProviderClusterRevision>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateProviderClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterOtaSoftwareUpdateRequestor(Commands & commands)
{
    using namespace chip::app::Clusters::OtaSoftwareUpdateRequestor;

    const char * clusterName = "OtaSoftwareUpdateRequestor";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<OtaSoftwareUpdateRequestorAnnounceOTAProvider>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadOtaSoftwareUpdateRequestorDefaultOTAProviders>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteOtaSoftwareUpdateRequestorDefaultOTAProviders>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorDefaultOTAProviders>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorUpdatePossible>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorUpdatePossible>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorUpdateState>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorUpdateState>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorUpdateStateProgress>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorUpdateStateProgress>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorGeneratedCommandList>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorGeneratedCommandList>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorAcceptedCommandList>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorAcceptedCommandList>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorAttributeList>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorAttributeList>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorFeatureMap>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorFeatureMap>(), //
        make_unique<ReadOtaSoftwareUpdateRequestorClusterRevision>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterLocalizationConfiguration(Commands & commands)
{
    using namespace chip::app::Clusters::LocalizationConfiguration;

    const char * clusterName = "LocalizationConfiguration";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadLocalizationConfigurationActiveLocale>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteLocalizationConfigurationActiveLocale>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeLocalizationConfigurationActiveLocale>(), //
        make_unique<ReadLocalizationConfigurationSupportedLocales>(), //
        make_unique<SubscribeAttributeLocalizationConfigurationSupportedLocales>(), //
        make_unique<ReadLocalizationConfigurationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeLocalizationConfigurationGeneratedCommandList>(), //
        make_unique<ReadLocalizationConfigurationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeLocalizationConfigurationAcceptedCommandList>(), //
        make_unique<ReadLocalizationConfigurationAttributeList>(), //
        make_unique<SubscribeAttributeLocalizationConfigurationAttributeList>(), //
        make_unique<ReadLocalizationConfigurationFeatureMap>(), //
        make_unique<SubscribeAttributeLocalizationConfigurationFeatureMap>(), //
        make_unique<ReadLocalizationConfigurationClusterRevision>(), //
        make_unique<SubscribeAttributeLocalizationConfigurationClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterTimeFormatLocalization(Commands & commands)
{
    using namespace chip::app::Clusters::TimeFormatLocalization;

    const char * clusterName = "TimeFormatLocalization";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadTimeFormatLocalizationHourFormat>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteTimeFormatLocalizationHourFormat>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeTimeFormatLocalizationHourFormat>(), //
        make_unique<ReadTimeFormatLocalizationActiveCalendarType>(), //
        make_unique<WriteTimeFormatLocalizationActiveCalendarType>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationActiveCalendarType>(), //
        make_unique<ReadTimeFormatLocalizationSupportedCalendarTypes>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationSupportedCalendarTypes>(), //
        make_unique<ReadTimeFormatLocalizationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationGeneratedCommandList>(), //
        make_unique<ReadTimeFormatLocalizationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationAcceptedCommandList>(), //
        make_unique<ReadTimeFormatLocalizationAttributeList>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationAttributeList>(), //
        make_unique<ReadTimeFormatLocalizationFeatureMap>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationFeatureMap>(), //
        make_unique<ReadTimeFormatLocalizationClusterRevision>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterUnitLocalization(Commands & commands)
{
    using namespace chip::app::Clusters::UnitLocalization;

    const char * clusterName = "UnitLocalization";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadUnitLocalizationTemperatureUnit>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteUnitLocalizationTemperatureUnit>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeUnitLocalizationTemperatureUnit>(), //
        make_unique<ReadUnitLocalizationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeUnitLocalizationGeneratedCommandList>(), //
        make_unique<ReadUnitLocalizationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeUnitLocalizationAcceptedCommandList>(), //
        make_unique<ReadUnitLocalizationAttributeList>(), //
        make_unique<SubscribeAttributeUnitLocalizationAttributeList>(), //
        make_unique<ReadUnitLocalizationFeatureMap>(), //
        make_unique<SubscribeAttributeUnitLocalizationFeatureMap>(), //
        make_unique<ReadUnitLocalizationClusterRevision>(), //
        make_unique<SubscribeAttributeUnitLocalizationClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterPowerSourceConfiguration(Commands & commands)
{
    using namespace chip::app::Clusters::PowerSourceConfiguration;

    const char * clusterName = "PowerSourceConfiguration";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadPowerSourceConfigurationSources>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributePowerSourceConfigurationSources>(), //
        make_unique<ReadPowerSourceConfigurationGeneratedCommandList>(), //
        make_unique<SubscribeAttributePowerSourceConfigurationGeneratedCommandList>(), //
        make_unique<ReadPowerSourceConfigurationAcceptedCommandList>(), //
        make_unique<SubscribeAttributePowerSourceConfigurationAcceptedCommandList>(), //
        make_unique<ReadPowerSourceConfigurationAttributeList>(), //
        make_unique<SubscribeAttributePowerSourceConfigurationAttributeList>(), //
        make_unique<ReadPowerSourceConfigurationFeatureMap>(), //
        make_unique<SubscribeAttributePowerSourceConfigurationFeatureMap>(), //
        make_unique<ReadPowerSourceConfigurationClusterRevision>(), //
        make_unique<SubscribeAttributePowerSourceConfigurationClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterPowerSource(Commands & commands)
{
    using namespace chip::app::Clusters::PowerSource;

    const char * clusterName = "PowerSource";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadPowerSourceStatus>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributePowerSourceStatus>(), //
        make_unique<ReadPowerSourceOrder>(), //
        make_unique<SubscribeAttributePowerSourceOrder>(), //
        make_unique<ReadPowerSourceDescription>(), //
        make_unique<SubscribeAttributePowerSourceDescription>(), //
        make_unique<ReadPowerSourceWiredAssessedInputVoltage>(), //
        make_unique<SubscribeAttributePowerSourceWiredAssessedInputVoltage>(), //
        make_unique<ReadPowerSourceWiredAssessedInputFrequency>(), //
        make_unique<SubscribeAttributePowerSourceWiredAssessedInputFrequency>(), //
        make_unique<ReadPowerSourceWiredCurrentType>(), //
        make_unique<SubscribeAttributePowerSourceWiredCurrentType>(), //
        make_unique<ReadPowerSourceWiredAssessedCurrent>(), //
        make_unique<SubscribeAttributePowerSourceWiredAssessedCurrent>(), //
        make_unique<ReadPowerSourceWiredNominalVoltage>(), //
        make_unique<SubscribeAttributePowerSourceWiredNominalVoltage>(), //
        make_unique<ReadPowerSourceWiredMaximumCurrent>(), //
        make_unique<SubscribeAttributePowerSourceWiredMaximumCurrent>(), //
        make_unique<ReadPowerSourceWiredPresent>(), //
        make_unique<SubscribeAttributePowerSourceWiredPresent>(), //
        make_unique<ReadPowerSourceActiveWiredFaults>(), //
        make_unique<SubscribeAttributePowerSourceActiveWiredFaults>(), //
        make_unique<ReadPowerSourceBatVoltage>(), //
        make_unique<SubscribeAttributePowerSourceBatVoltage>(), //
        make_unique<ReadPowerSourceBatPercentRemaining>(), //
        make_unique<SubscribeAttributePowerSourceBatPercentRemaining>(), //
        make_unique<ReadPowerSourceBatTimeRemaining>(), //
        make_unique<SubscribeAttributePowerSourceBatTimeRemaining>(), //
        make_unique<ReadPowerSourceBatChargeLevel>(), //
        make_unique<SubscribeAttributePowerSourceBatChargeLevel>(), //
        make_unique<ReadPowerSourceBatReplacementNeeded>(), //
        make_unique<SubscribeAttributePowerSourceBatReplacementNeeded>(), //
        make_unique<ReadPowerSourceBatReplaceability>(), //
        make_unique<SubscribeAttributePowerSourceBatReplaceability>(), //
        make_unique<ReadPowerSourceBatPresent>(), //
        make_unique<SubscribeAttributePowerSourceBatPresent>(), //
        make_unique<ReadPowerSourceActiveBatFaults>(), //
        make_unique<SubscribeAttributePowerSourceActiveBatFaults>(), //
        make_unique<ReadPowerSourceBatReplacementDescription>(), //
        make_unique<SubscribeAttributePowerSourceBatReplacementDescription>(), //
        make_unique<ReadPowerSourceBatCommonDesignation>(), //
        make_unique<SubscribeAttributePowerSourceBatCommonDesignation>(), //
        make_unique<ReadPowerSourceBatANSIDesignation>(), //
        make_unique<SubscribeAttributePowerSourceBatANSIDesignation>(), //
        make_unique<ReadPowerSourceBatIECDesignation>(), //
        make_unique<SubscribeAttributePowerSourceBatIECDesignation>(), //
        make_unique<ReadPowerSourceBatApprovedChemistry>(), //
        make_unique<SubscribeAttributePowerSourceBatApprovedChemistry>(), //
        make_unique<ReadPowerSourceBatCapacity>(), //
        make_unique<SubscribeAttributePowerSourceBatCapacity>(), //
        make_unique<ReadPowerSourceBatQuantity>(), //
        make_unique<SubscribeAttributePowerSourceBatQuantity>(), //
        make_unique<ReadPowerSourceBatChargeState>(), //
        make_unique<SubscribeAttributePowerSourceBatChargeState>(), //
        make_unique<ReadPowerSourceBatTimeToFullCharge>(), //
        make_unique<SubscribeAttributePowerSourceBatTimeToFullCharge>(), //
        make_unique<ReadPowerSourceBatFunctionalWhileCharging>(), //
        make_unique<SubscribeAttributePowerSourceBatFunctionalWhileCharging>(), //
        make_unique<ReadPowerSourceBatChargingCurrent>(), //
        make_unique<SubscribeAttributePowerSourceBatChargingCurrent>(), //
        make_unique<ReadPowerSourceActiveBatChargeFaults>(), //
        make_unique<SubscribeAttributePowerSourceActiveBatChargeFaults>(), //
        make_unique<ReadPowerSourceGeneratedCommandList>(), //
        make_unique<SubscribeAttributePowerSourceGeneratedCommandList>(), //
        make_unique<ReadPowerSourceAcceptedCommandList>(), //
        make_unique<SubscribeAttributePowerSourceAcceptedCommandList>(), //
        make_unique<ReadPowerSourceAttributeList>(), //
        make_unique<SubscribeAttributePowerSourceAttributeList>(), //
        make_unique<ReadPowerSourceFeatureMap>(), //
        make_unique<SubscribeAttributePowerSourceFeatureMap>(), //
        make_unique<ReadPowerSourceClusterRevision>(), //
        make_unique<SubscribeAttributePowerSourceClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterGeneralCommissioning(Commands & commands)
{
    using namespace chip::app::Clusters::GeneralCommissioning;

    const char * clusterName = "GeneralCommissioning";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<GeneralCommissioningArmFailSafe>(), //
        make_unique<GeneralCommissioningSetRegulatoryConfig>(), //
        make_unique<GeneralCommissioningCommissioningComplete>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadGeneralCommissioningBreadcrumb>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteGeneralCommissioningBreadcrumb>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeGeneralCommissioningBreadcrumb>(), //
        make_unique<ReadGeneralCommissioningBasicCommissioningInfo>(), //
        make_unique<SubscribeAttributeGeneralCommissioningBasicCommissioningInfo>(), //
        make_unique<ReadGeneralCommissioningRegulatoryConfig>(), //
        make_unique<SubscribeAttributeGeneralCommissioningRegulatoryConfig>(), //
        make_unique<ReadGeneralCommissioningLocationCapability>(), //
        make_unique<SubscribeAttributeGeneralCommissioningLocationCapability>(), //
        make_unique<ReadGeneralCommissioningSupportsConcurrentConnection>(), //
        make_unique<SubscribeAttributeGeneralCommissioningSupportsConcurrentConnection>(), //
        make_unique<ReadGeneralCommissioningGeneratedCommandList>(), //
        make_unique<SubscribeAttributeGeneralCommissioningGeneratedCommandList>(), //
        make_unique<ReadGeneralCommissioningAcceptedCommandList>(), //
        make_unique<SubscribeAttributeGeneralCommissioningAcceptedCommandList>(), //
        make_unique<ReadGeneralCommissioningAttributeList>(), //
        make_unique<SubscribeAttributeGeneralCommissioningAttributeList>(), //
        make_unique<ReadGeneralCommissioningFeatureMap>(), //
        make_unique<SubscribeAttributeGeneralCommissioningFeatureMap>(), //
        make_unique<ReadGeneralCommissioningClusterRevision>(), //
        make_unique<SubscribeAttributeGeneralCommissioningClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterNetworkCommissioning(Commands & commands)
{
    using namespace chip::app::Clusters::NetworkCommissioning;

    const char * clusterName = "NetworkCommissioning";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<NetworkCommissioningScanNetworks>(), //
        make_unique<NetworkCommissioningAddOrUpdateWiFiNetwork>(), //
        make_unique<NetworkCommissioningAddOrUpdateThreadNetwork>(), //
        make_unique<NetworkCommissioningRemoveNetwork>(), //
        make_unique<NetworkCommissioningConnectNetwork>(), //
        make_unique<NetworkCommissioningReorderNetwork>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadNetworkCommissioningMaxNetworks>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeNetworkCommissioningMaxNetworks>(), //
        make_unique<ReadNetworkCommissioningNetworks>(), //
        make_unique<SubscribeAttributeNetworkCommissioningNetworks>(), //
        make_unique<ReadNetworkCommissioningScanMaxTimeSeconds>(), //
        make_unique<SubscribeAttributeNetworkCommissioningScanMaxTimeSeconds>(), //
        make_unique<ReadNetworkCommissioningConnectMaxTimeSeconds>(), //
        make_unique<SubscribeAttributeNetworkCommissioningConnectMaxTimeSeconds>(), //
        make_unique<ReadNetworkCommissioningInterfaceEnabled>(), //
        make_unique<WriteNetworkCommissioningInterfaceEnabled>(), //
        make_unique<SubscribeAttributeNetworkCommissioningInterfaceEnabled>(), //
        make_unique<ReadNetworkCommissioningLastNetworkingStatus>(), //
        make_unique<SubscribeAttributeNetworkCommissioningLastNetworkingStatus>(), //
        make_unique<ReadNetworkCommissioningLastNetworkID>(), //
        make_unique<SubscribeAttributeNetworkCommissioningLastNetworkID>(), //
        make_unique<ReadNetworkCommissioningLastConnectErrorValue>(), //
        make_unique<SubscribeAttributeNetworkCommissioningLastConnectErrorValue>(), //
        make_unique<ReadNetworkCommissioningGeneratedCommandList>(), //
        make_unique<SubscribeAttributeNetworkCommissioningGeneratedCommandList>(), //
        make_unique<ReadNetworkCommissioningAcceptedCommandList>(), //
        make_unique<SubscribeAttributeNetworkCommissioningAcceptedCommandList>(), //
        make_unique<ReadNetworkCommissioningAttributeList>(), //
        make_unique<SubscribeAttributeNetworkCommissioningAttributeList>(), //
        make_unique<ReadNetworkCommissioningFeatureMap>(), //
        make_unique<SubscribeAttributeNetworkCommissioningFeatureMap>(), //
        make_unique<ReadNetworkCommissioningClusterRevision>(), //
        make_unique<SubscribeAttributeNetworkCommissioningClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterDiagnosticLogs(Commands & commands)
{
    using namespace chip::app::Clusters::DiagnosticLogs;

    const char * clusterName = "DiagnosticLogs";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<DiagnosticLogsRetrieveLogsRequest>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadDiagnosticLogsGeneratedCommandList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeDiagnosticLogsGeneratedCommandList>(), //
        make_unique<ReadDiagnosticLogsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeDiagnosticLogsAcceptedCommandList>(), //
        make_unique<ReadDiagnosticLogsAttributeList>(), //
        make_unique<SubscribeAttributeDiagnosticLogsAttributeList>(), //
        make_unique<ReadDiagnosticLogsFeatureMap>(), //
        make_unique<SubscribeAttributeDiagnosticLogsFeatureMap>(), //
        make_unique<ReadDiagnosticLogsClusterRevision>(), //
        make_unique<SubscribeAttributeDiagnosticLogsClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterGeneralDiagnostics(Commands & commands)
{
    using namespace chip::app::Clusters::GeneralDiagnostics;

    const char * clusterName = "GeneralDiagnostics";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<GeneralDiagnosticsTestEventTrigger>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadGeneralDiagnosticsNetworkInterfaces>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeGeneralDiagnosticsNetworkInterfaces>(), //
        make_unique<ReadGeneralDiagnosticsRebootCount>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsRebootCount>(), //
        make_unique<ReadGeneralDiagnosticsUpTime>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsUpTime>(), //
        make_unique<ReadGeneralDiagnosticsTotalOperationalHours>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsTotalOperationalHours>(), //
        make_unique<ReadGeneralDiagnosticsBootReason>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsBootReason>(), //
        make_unique<ReadGeneralDiagnosticsActiveHardwareFaults>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsActiveHardwareFaults>(), //
        make_unique<ReadGeneralDiagnosticsActiveRadioFaults>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsActiveRadioFaults>(), //
        make_unique<ReadGeneralDiagnosticsActiveNetworkFaults>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsActiveNetworkFaults>(), //
        make_unique<ReadGeneralDiagnosticsTestEventTriggersEnabled>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsTestEventTriggersEnabled>(), //
        make_unique<ReadGeneralDiagnosticsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsGeneratedCommandList>(), //
        make_unique<ReadGeneralDiagnosticsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsAcceptedCommandList>(), //
        make_unique<ReadGeneralDiagnosticsAttributeList>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsAttributeList>(), //
        make_unique<ReadGeneralDiagnosticsFeatureMap>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsFeatureMap>(), //
        make_unique<ReadGeneralDiagnosticsClusterRevision>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterSoftwareDiagnostics(Commands & commands)
{
    using namespace chip::app::Clusters::SoftwareDiagnostics;

    const char * clusterName = "SoftwareDiagnostics";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<SoftwareDiagnosticsResetWatermarks>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadSoftwareDiagnosticsThreadMetrics>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsThreadMetrics>(), //
        make_unique<ReadSoftwareDiagnosticsCurrentHeapFree>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsCurrentHeapFree>(), //
        make_unique<ReadSoftwareDiagnosticsCurrentHeapUsed>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsCurrentHeapUsed>(), //
        make_unique<ReadSoftwareDiagnosticsCurrentHeapHighWatermark>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsCurrentHeapHighWatermark>(), //
        make_unique<ReadSoftwareDiagnosticsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsGeneratedCommandList>(), //
        make_unique<ReadSoftwareDiagnosticsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsAcceptedCommandList>(), //
        make_unique<ReadSoftwareDiagnosticsAttributeList>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsAttributeList>(), //
        make_unique<ReadSoftwareDiagnosticsFeatureMap>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsFeatureMap>(), //
        make_unique<ReadSoftwareDiagnosticsClusterRevision>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterThreadNetworkDiagnostics(Commands & commands)
{
    using namespace chip::app::Clusters::ThreadNetworkDiagnostics;

    const char * clusterName = "ThreadNetworkDiagnostics";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ThreadNetworkDiagnosticsResetCounts>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadThreadNetworkDiagnosticsChannel>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsChannel>(), //
        make_unique<ReadThreadNetworkDiagnosticsRoutingRole>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRoutingRole>(), //
        make_unique<ReadThreadNetworkDiagnosticsNetworkName>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsNetworkName>(), //
        make_unique<ReadThreadNetworkDiagnosticsPanId>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsPanId>(), //
        make_unique<ReadThreadNetworkDiagnosticsExtendedPanId>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsExtendedPanId>(), //
        make_unique<ReadThreadNetworkDiagnosticsMeshLocalPrefix>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsMeshLocalPrefix>(), //
        make_unique<ReadThreadNetworkDiagnosticsOverrunCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsOverrunCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsNeighborTable>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsNeighborTable>(), //
        make_unique<ReadThreadNetworkDiagnosticsRouteTable>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRouteTable>(), //
        make_unique<ReadThreadNetworkDiagnosticsPartitionId>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsPartitionId>(), //
        make_unique<ReadThreadNetworkDiagnosticsWeighting>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsWeighting>(), //
        make_unique<ReadThreadNetworkDiagnosticsDataVersion>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsDataVersion>(), //
        make_unique<ReadThreadNetworkDiagnosticsStableDataVersion>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsStableDataVersion>(), //
        make_unique<ReadThreadNetworkDiagnosticsLeaderRouterId>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsLeaderRouterId>(), //
        make_unique<ReadThreadNetworkDiagnosticsDetachedRoleCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsDetachedRoleCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsChildRoleCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsChildRoleCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRouterRoleCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRouterRoleCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsLeaderRoleCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsLeaderRoleCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsAttachAttemptCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsAttachAttemptCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsPartitionIdChangeCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsPartitionIdChangeCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsBetterPartitionAttachAttemptCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsParentChangeCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsParentChangeCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxTotalCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxTotalCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxUnicastCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxUnicastCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxBroadcastCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxBroadcastCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxAckRequestedCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxAckRequestedCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxAckedCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxAckedCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxNoAckRequestedCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxNoAckRequestedCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxDataCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxDataCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxDataPollCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxDataPollCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxBeaconCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxBeaconCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxBeaconRequestCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxBeaconRequestCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxOtherCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxOtherCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxRetryCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxRetryCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxDirectMaxRetryExpiryCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxIndirectMaxRetryExpiryCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxErrCcaCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxErrCcaCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxErrAbortCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxErrAbortCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsTxErrBusyChannelCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsTxErrBusyChannelCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxTotalCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxTotalCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxUnicastCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxUnicastCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxBroadcastCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxBroadcastCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxDataCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxDataCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxDataPollCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxDataPollCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxBeaconCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxBeaconCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxBeaconRequestCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxBeaconRequestCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxOtherCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxOtherCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxAddressFilteredCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxAddressFilteredCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxDestAddrFilteredCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxDestAddrFilteredCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxDuplicatedCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxDuplicatedCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxErrNoFrameCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxErrNoFrameCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxErrUnknownNeighborCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxErrUnknownNeighborCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxErrInvalidSrcAddrCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxErrSecCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxErrSecCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxErrFcsCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxErrFcsCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsRxErrOtherCount>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsRxErrOtherCount>(), //
        make_unique<ReadThreadNetworkDiagnosticsActiveTimestamp>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsActiveTimestamp>(), //
        make_unique<ReadThreadNetworkDiagnosticsPendingTimestamp>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsPendingTimestamp>(), //
        make_unique<ReadThreadNetworkDiagnosticsDelay>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsDelay>(), //
        make_unique<ReadThreadNetworkDiagnosticsSecurityPolicy>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsSecurityPolicy>(), //
        make_unique<ReadThreadNetworkDiagnosticsChannelPage0Mask>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsChannelPage0Mask>(), //
        make_unique<ReadThreadNetworkDiagnosticsOperationalDatasetComponents>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsOperationalDatasetComponents>(), //
        make_unique<ReadThreadNetworkDiagnosticsActiveNetworkFaultsList>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsActiveNetworkFaultsList>(), //
        make_unique<ReadThreadNetworkDiagnosticsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsGeneratedCommandList>(), //
        make_unique<ReadThreadNetworkDiagnosticsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsAcceptedCommandList>(), //
        make_unique<ReadThreadNetworkDiagnosticsAttributeList>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsAttributeList>(), //
        make_unique<ReadThreadNetworkDiagnosticsFeatureMap>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsFeatureMap>(), //
        make_unique<ReadThreadNetworkDiagnosticsClusterRevision>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterWiFiNetworkDiagnostics(Commands & commands)
{
    using namespace chip::app::Clusters::WiFiNetworkDiagnostics;

    const char * clusterName = "WiFiNetworkDiagnostics";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<WiFiNetworkDiagnosticsResetCounts>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadWiFiNetworkDiagnosticsBssid>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsBssid>(), //
        make_unique<ReadWiFiNetworkDiagnosticsSecurityType>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsSecurityType>(), //
        make_unique<ReadWiFiNetworkDiagnosticsWiFiVersion>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsWiFiVersion>(), //
        make_unique<ReadWiFiNetworkDiagnosticsChannelNumber>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsChannelNumber>(), //
        make_unique<ReadWiFiNetworkDiagnosticsRssi>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsRssi>(), //
        make_unique<ReadWiFiNetworkDiagnosticsBeaconLostCount>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsBeaconLostCount>(), //
        make_unique<ReadWiFiNetworkDiagnosticsBeaconRxCount>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsBeaconRxCount>(), //
        make_unique<ReadWiFiNetworkDiagnosticsPacketMulticastRxCount>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastRxCount>(), //
        make_unique<ReadWiFiNetworkDiagnosticsPacketMulticastTxCount>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsPacketMulticastTxCount>(), //
        make_unique<ReadWiFiNetworkDiagnosticsPacketUnicastRxCount>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastRxCount>(), //
        make_unique<ReadWiFiNetworkDiagnosticsPacketUnicastTxCount>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsPacketUnicastTxCount>(), //
        make_unique<ReadWiFiNetworkDiagnosticsCurrentMaxRate>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsCurrentMaxRate>(), //
        make_unique<ReadWiFiNetworkDiagnosticsOverrunCount>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsOverrunCount>(), //
        make_unique<ReadWiFiNetworkDiagnosticsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsGeneratedCommandList>(), //
        make_unique<ReadWiFiNetworkDiagnosticsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsAcceptedCommandList>(), //
        make_unique<ReadWiFiNetworkDiagnosticsAttributeList>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsAttributeList>(), //
        make_unique<ReadWiFiNetworkDiagnosticsFeatureMap>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsFeatureMap>(), //
        make_unique<ReadWiFiNetworkDiagnosticsClusterRevision>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterEthernetNetworkDiagnostics(Commands & commands)
{
    using namespace chip::app::Clusters::EthernetNetworkDiagnostics;

    const char * clusterName = "EthernetNetworkDiagnostics";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<EthernetNetworkDiagnosticsResetCounts>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadEthernetNetworkDiagnosticsPHYRate>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsPHYRate>(), //
        make_unique<ReadEthernetNetworkDiagnosticsFullDuplex>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsFullDuplex>(), //
        make_unique<ReadEthernetNetworkDiagnosticsPacketRxCount>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsPacketRxCount>(), //
        make_unique<ReadEthernetNetworkDiagnosticsPacketTxCount>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsPacketTxCount>(), //
        make_unique<ReadEthernetNetworkDiagnosticsTxErrCount>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsTxErrCount>(), //
        make_unique<ReadEthernetNetworkDiagnosticsCollisionCount>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsCollisionCount>(), //
        make_unique<ReadEthernetNetworkDiagnosticsOverrunCount>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsOverrunCount>(), //
        make_unique<ReadEthernetNetworkDiagnosticsCarrierDetect>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsCarrierDetect>(), //
        make_unique<ReadEthernetNetworkDiagnosticsTimeSinceReset>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsTimeSinceReset>(), //
        make_unique<ReadEthernetNetworkDiagnosticsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsGeneratedCommandList>(), //
        make_unique<ReadEthernetNetworkDiagnosticsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsAcceptedCommandList>(), //
        make_unique<ReadEthernetNetworkDiagnosticsAttributeList>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsAttributeList>(), //
        make_unique<ReadEthernetNetworkDiagnosticsFeatureMap>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsFeatureMap>(), //
        make_unique<ReadEthernetNetworkDiagnosticsClusterRevision>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterBridgedDeviceBasicInformation(Commands & commands)
{
    using namespace chip::app::Clusters::BridgedDeviceBasicInformation;

    const char * clusterName = "BridgedDeviceBasicInformation";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadBridgedDeviceBasicInformationVendorName>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationVendorName>(), //
        make_unique<ReadBridgedDeviceBasicInformationVendorID>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationVendorID>(), //
        make_unique<ReadBridgedDeviceBasicInformationProductName>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationProductName>(), //
        make_unique<ReadBridgedDeviceBasicInformationNodeLabel>(), //
        make_unique<WriteBridgedDeviceBasicInformationNodeLabel>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationNodeLabel>(), //
        make_unique<ReadBridgedDeviceBasicInformationHardwareVersion>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationHardwareVersion>(), //
        make_unique<ReadBridgedDeviceBasicInformationHardwareVersionString>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationHardwareVersionString>(), //
        make_unique<ReadBridgedDeviceBasicInformationSoftwareVersion>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersion>(), //
        make_unique<ReadBridgedDeviceBasicInformationSoftwareVersionString>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationSoftwareVersionString>(), //
        make_unique<ReadBridgedDeviceBasicInformationManufacturingDate>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationManufacturingDate>(), //
        make_unique<ReadBridgedDeviceBasicInformationPartNumber>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationPartNumber>(), //
        make_unique<ReadBridgedDeviceBasicInformationProductURL>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationProductURL>(), //
        make_unique<ReadBridgedDeviceBasicInformationProductLabel>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationProductLabel>(), //
        make_unique<ReadBridgedDeviceBasicInformationSerialNumber>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationSerialNumber>(), //
        make_unique<ReadBridgedDeviceBasicInformationReachable>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationReachable>(), //
        make_unique<ReadBridgedDeviceBasicInformationUniqueID>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationUniqueID>(), //
        make_unique<ReadBridgedDeviceBasicInformationProductAppearance>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationProductAppearance>(), //
        make_unique<ReadBridgedDeviceBasicInformationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationGeneratedCommandList>(), //
        make_unique<ReadBridgedDeviceBasicInformationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationAcceptedCommandList>(), //
        make_unique<ReadBridgedDeviceBasicInformationAttributeList>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationAttributeList>(), //
        make_unique<ReadBridgedDeviceBasicInformationFeatureMap>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationFeatureMap>(), //
        make_unique<ReadBridgedDeviceBasicInformationClusterRevision>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterSwitch(Commands & commands)
{
    using namespace chip::app::Clusters::Switch;

    const char * clusterName = "Switch";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadSwitchNumberOfPositions>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeSwitchNumberOfPositions>(), //
        make_unique<ReadSwitchCurrentPosition>(), //
        make_unique<SubscribeAttributeSwitchCurrentPosition>(), //
        make_unique<ReadSwitchMultiPressMax>(), //
        make_unique<SubscribeAttributeSwitchMultiPressMax>(), //
        make_unique<ReadSwitchGeneratedCommandList>(), //
        make_unique<SubscribeAttributeSwitchGeneratedCommandList>(), //
        make_unique<ReadSwitchAcceptedCommandList>(), //
        make_unique<SubscribeAttributeSwitchAcceptedCommandList>(), //
        make_unique<ReadSwitchAttributeList>(), //
        make_unique<SubscribeAttributeSwitchAttributeList>(), //
        make_unique<ReadSwitchFeatureMap>(), //
        make_unique<SubscribeAttributeSwitchFeatureMap>(), //
        make_unique<ReadSwitchClusterRevision>(), //
        make_unique<SubscribeAttributeSwitchClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterAdministratorCommissioning(Commands & commands)
{
    using namespace chip::app::Clusters::AdministratorCommissioning;

    const char * clusterName = "AdministratorCommissioning";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<AdministratorCommissioningOpenCommissioningWindow>(), //
        make_unique<AdministratorCommissioningOpenBasicCommissioningWindow>(), //
        make_unique<AdministratorCommissioningRevokeCommissioning>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadAdministratorCommissioningWindowStatus>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeAdministratorCommissioningWindowStatus>(), //
        make_unique<ReadAdministratorCommissioningAdminFabricIndex>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningAdminFabricIndex>(), //
        make_unique<ReadAdministratorCommissioningAdminVendorId>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningAdminVendorId>(), //
        make_unique<ReadAdministratorCommissioningGeneratedCommandList>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningGeneratedCommandList>(), //
        make_unique<ReadAdministratorCommissioningAcceptedCommandList>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningAcceptedCommandList>(), //
        make_unique<ReadAdministratorCommissioningAttributeList>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningAttributeList>(), //
        make_unique<ReadAdministratorCommissioningFeatureMap>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningFeatureMap>(), //
        make_unique<ReadAdministratorCommissioningClusterRevision>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterOperationalCredentials(Commands & commands)
{
    using namespace chip::app::Clusters::OperationalCredentials;

    const char * clusterName = "OperationalCredentials";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<OperationalCredentialsAttestationRequest>(), //
        make_unique<OperationalCredentialsCertificateChainRequest>(), //
        make_unique<OperationalCredentialsCSRRequest>(), //
        make_unique<OperationalCredentialsAddNOC>(), //
        make_unique<OperationalCredentialsUpdateNOC>(), //
        make_unique<OperationalCredentialsUpdateFabricLabel>(), //
        make_unique<OperationalCredentialsRemoveFabric>(), //
        make_unique<OperationalCredentialsAddTrustedRootCertificate>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadOperationalCredentialsNOCs>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeOperationalCredentialsNOCs>(), //
        make_unique<ReadOperationalCredentialsFabrics>(), //
        make_unique<SubscribeAttributeOperationalCredentialsFabrics>(), //
        make_unique<ReadOperationalCredentialsSupportedFabrics>(), //
        make_unique<SubscribeAttributeOperationalCredentialsSupportedFabrics>(), //
        make_unique<ReadOperationalCredentialsCommissionedFabrics>(), //
        make_unique<SubscribeAttributeOperationalCredentialsCommissionedFabrics>(), //
        make_unique<ReadOperationalCredentialsTrustedRootCertificates>(), //
        make_unique<SubscribeAttributeOperationalCredentialsTrustedRootCertificates>(), //
        make_unique<ReadOperationalCredentialsCurrentFabricIndex>(), //
        make_unique<SubscribeAttributeOperationalCredentialsCurrentFabricIndex>(), //
        make_unique<ReadOperationalCredentialsGeneratedCommandList>(), //
        make_unique<SubscribeAttributeOperationalCredentialsGeneratedCommandList>(), //
        make_unique<ReadOperationalCredentialsAcceptedCommandList>(), //
        make_unique<SubscribeAttributeOperationalCredentialsAcceptedCommandList>(), //
        make_unique<ReadOperationalCredentialsAttributeList>(), //
        make_unique<SubscribeAttributeOperationalCredentialsAttributeList>(), //
        make_unique<ReadOperationalCredentialsFeatureMap>(), //
        make_unique<SubscribeAttributeOperationalCredentialsFeatureMap>(), //
        make_unique<ReadOperationalCredentialsClusterRevision>(), //
        make_unique<SubscribeAttributeOperationalCredentialsClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterGroupKeyManagement(Commands & commands)
{
    using namespace chip::app::Clusters::GroupKeyManagement;

    const char * clusterName = "GroupKeyManagement";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<GroupKeyManagementKeySetWrite>(), //
        make_unique<GroupKeyManagementKeySetRead>(), //
        make_unique<GroupKeyManagementKeySetRemove>(), //
        make_unique<GroupKeyManagementKeySetReadAllIndices>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadGroupKeyManagementGroupKeyMap>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteGroupKeyManagementGroupKeyMap>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeGroupKeyManagementGroupKeyMap>(), //
        make_unique<ReadGroupKeyManagementGroupTable>(), //
        make_unique<SubscribeAttributeGroupKeyManagementGroupTable>(), //
        make_unique<ReadGroupKeyManagementMaxGroupsPerFabric>(), //
        make_unique<SubscribeAttributeGroupKeyManagementMaxGroupsPerFabric>(), //
        make_unique<ReadGroupKeyManagementMaxGroupKeysPerFabric>(), //
        make_unique<SubscribeAttributeGroupKeyManagementMaxGroupKeysPerFabric>(), //
        make_unique<ReadGroupKeyManagementGeneratedCommandList>(), //
        make_unique<SubscribeAttributeGroupKeyManagementGeneratedCommandList>(), //
        make_unique<ReadGroupKeyManagementAcceptedCommandList>(), //
        make_unique<SubscribeAttributeGroupKeyManagementAcceptedCommandList>(), //
        make_unique<ReadGroupKeyManagementAttributeList>(), //
        make_unique<SubscribeAttributeGroupKeyManagementAttributeList>(), //
        make_unique<ReadGroupKeyManagementFeatureMap>(), //
        make_unique<SubscribeAttributeGroupKeyManagementFeatureMap>(), //
        make_unique<ReadGroupKeyManagementClusterRevision>(), //
        make_unique<SubscribeAttributeGroupKeyManagementClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterFixedLabel(Commands & commands)
{
    using namespace chip::app::Clusters::FixedLabel;

    const char * clusterName = "FixedLabel";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadFixedLabelLabelList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeFixedLabelLabelList>(), //
        make_unique<ReadFixedLabelGeneratedCommandList>(), //
        make_unique<SubscribeAttributeFixedLabelGeneratedCommandList>(), //
        make_unique<ReadFixedLabelAcceptedCommandList>(), //
        make_unique<SubscribeAttributeFixedLabelAcceptedCommandList>(), //
        make_unique<ReadFixedLabelAttributeList>(), //
        make_unique<SubscribeAttributeFixedLabelAttributeList>(), //
        make_unique<ReadFixedLabelFeatureMap>(), //
        make_unique<SubscribeAttributeFixedLabelFeatureMap>(), //
        make_unique<ReadFixedLabelClusterRevision>(), //
        make_unique<SubscribeAttributeFixedLabelClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterUserLabel(Commands & commands)
{
    using namespace chip::app::Clusters::UserLabel;

    const char * clusterName = "UserLabel";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadUserLabelLabelList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteUserLabelLabelList>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeUserLabelLabelList>(), //
        make_unique<ReadUserLabelGeneratedCommandList>(), //
        make_unique<SubscribeAttributeUserLabelGeneratedCommandList>(), //
        make_unique<ReadUserLabelAcceptedCommandList>(), //
        make_unique<SubscribeAttributeUserLabelAcceptedCommandList>(), //
        make_unique<ReadUserLabelAttributeList>(), //
        make_unique<SubscribeAttributeUserLabelAttributeList>(), //
        make_unique<ReadUserLabelFeatureMap>(), //
        make_unique<SubscribeAttributeUserLabelFeatureMap>(), //
        make_unique<ReadUserLabelClusterRevision>(), //
        make_unique<SubscribeAttributeUserLabelClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterBooleanState(Commands & commands)
{
    using namespace chip::app::Clusters::BooleanState;

    const char * clusterName = "BooleanState";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadBooleanStateStateValue>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeBooleanStateStateValue>(), //
        make_unique<ReadBooleanStateGeneratedCommandList>(), //
        make_unique<SubscribeAttributeBooleanStateGeneratedCommandList>(), //
        make_unique<ReadBooleanStateAcceptedCommandList>(), //
        make_unique<SubscribeAttributeBooleanStateAcceptedCommandList>(), //
        make_unique<ReadBooleanStateAttributeList>(), //
        make_unique<SubscribeAttributeBooleanStateAttributeList>(), //
        make_unique<ReadBooleanStateFeatureMap>(), //
        make_unique<SubscribeAttributeBooleanStateFeatureMap>(), //
        make_unique<ReadBooleanStateClusterRevision>(), //
        make_unique<SubscribeAttributeBooleanStateClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterModeSelect(Commands & commands)
{
    using namespace chip::app::Clusters::ModeSelect;

    const char * clusterName = "ModeSelect";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ModeSelectChangeToMode>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadModeSelectDescription>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeModeSelectDescription>(), //
        make_unique<ReadModeSelectStandardNamespace>(), //
        make_unique<SubscribeAttributeModeSelectStandardNamespace>(), //
        make_unique<ReadModeSelectSupportedModes>(), //
        make_unique<SubscribeAttributeModeSelectSupportedModes>(), //
        make_unique<ReadModeSelectCurrentMode>(), //
        make_unique<SubscribeAttributeModeSelectCurrentMode>(), //
        make_unique<ReadModeSelectStartUpMode>(), //
        make_unique<WriteModeSelectStartUpMode>(), //
        make_unique<SubscribeAttributeModeSelectStartUpMode>(), //
        make_unique<ReadModeSelectOnMode>(), //
        make_unique<WriteModeSelectOnMode>(), //
        make_unique<SubscribeAttributeModeSelectOnMode>(), //
        make_unique<ReadModeSelectGeneratedCommandList>(), //
        make_unique<SubscribeAttributeModeSelectGeneratedCommandList>(), //
        make_unique<ReadModeSelectAcceptedCommandList>(), //
        make_unique<SubscribeAttributeModeSelectAcceptedCommandList>(), //
        make_unique<ReadModeSelectAttributeList>(), //
        make_unique<SubscribeAttributeModeSelectAttributeList>(), //
        make_unique<ReadModeSelectFeatureMap>(), //
        make_unique<SubscribeAttributeModeSelectFeatureMap>(), //
        make_unique<ReadModeSelectClusterRevision>(), //
        make_unique<SubscribeAttributeModeSelectClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterHepaFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::HepaFilterMonitoring;

    const char * clusterName = "HepaFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<HepaFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadHepaFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeHepaFilterMonitoringCondition>(), //
        make_unique<ReadHepaFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringDegradationDirection>(), //
        make_unique<ReadHepaFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringChangeIndication>(), //
        make_unique<ReadHepaFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadHepaFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadHepaFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadHepaFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringEventList>(), //
        make_unique<ReadHepaFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringAttributeList>(), //
        make_unique<ReadHepaFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringFeatureMap>(), //
        make_unique<ReadHepaFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeHepaFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterActivatedCarbonFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::ActivatedCarbonFilterMonitoring;

    const char * clusterName = "ActivatedCarbonFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ActivatedCarbonFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadActivatedCarbonFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringCondition>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringDegradationDirection>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringChangeIndication>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringEventList>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringAttributeList>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringFeatureMap>(), //
        make_unique<ReadActivatedCarbonFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeActivatedCarbonFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterCeramicFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::CeramicFilterMonitoring;

    const char * clusterName = "CeramicFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<CeramicFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadCeramicFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringCondition>(), //
        make_unique<ReadCeramicFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringDegradationDirection>(), //
        make_unique<ReadCeramicFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringChangeIndication>(), //
        make_unique<ReadCeramicFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadCeramicFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadCeramicFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadCeramicFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringEventList>(), //
        make_unique<ReadCeramicFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringAttributeList>(), //
        make_unique<ReadCeramicFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringFeatureMap>(), //
        make_unique<ReadCeramicFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeCeramicFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterElectrostaticFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::ElectrostaticFilterMonitoring;

    const char * clusterName = "ElectrostaticFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ElectrostaticFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadElectrostaticFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringCondition>(), //
        make_unique<ReadElectrostaticFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringDegradationDirection>(), //
        make_unique<ReadElectrostaticFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringChangeIndication>(), //
        make_unique<ReadElectrostaticFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadElectrostaticFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadElectrostaticFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadElectrostaticFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringEventList>(), //
        make_unique<ReadElectrostaticFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringAttributeList>(), //
        make_unique<ReadElectrostaticFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringFeatureMap>(), //
        make_unique<ReadElectrostaticFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeElectrostaticFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterUvFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::UvFilterMonitoring;

    const char * clusterName = "UvFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<UvFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadUvFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeUvFilterMonitoringCondition>(), //
        make_unique<ReadUvFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringDegradationDirection>(), //
        make_unique<ReadUvFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringChangeIndication>(), //
        make_unique<ReadUvFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadUvFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadUvFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadUvFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringEventList>(), //
        make_unique<ReadUvFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringAttributeList>(), //
        make_unique<ReadUvFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringFeatureMap>(), //
        make_unique<ReadUvFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeUvFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterIonizingFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::IonizingFilterMonitoring;

    const char * clusterName = "IonizingFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<IonizingFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadIonizingFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringCondition>(), //
        make_unique<ReadIonizingFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringDegradationDirection>(), //
        make_unique<ReadIonizingFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringChangeIndication>(), //
        make_unique<ReadIonizingFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadIonizingFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadIonizingFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadIonizingFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringEventList>(), //
        make_unique<ReadIonizingFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringAttributeList>(), //
        make_unique<ReadIonizingFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringFeatureMap>(), //
        make_unique<ReadIonizingFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeIonizingFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterZeoliteFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::ZeoliteFilterMonitoring;

    const char * clusterName = "ZeoliteFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ZeoliteFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadZeoliteFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringCondition>(), //
        make_unique<ReadZeoliteFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringDegradationDirection>(), //
        make_unique<ReadZeoliteFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringChangeIndication>(), //
        make_unique<ReadZeoliteFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadZeoliteFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadZeoliteFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadZeoliteFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringEventList>(), //
        make_unique<ReadZeoliteFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringAttributeList>(), //
        make_unique<ReadZeoliteFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringFeatureMap>(), //
        make_unique<ReadZeoliteFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeZeoliteFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterOzoneFilterMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::OzoneFilterMonitoring;

    const char * clusterName = "OzoneFilterMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<OzoneFilterMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadOzoneFilterMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringCondition>(), //
        make_unique<ReadOzoneFilterMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringDegradationDirection>(), //
        make_unique<ReadOzoneFilterMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringChangeIndication>(), //
        make_unique<ReadOzoneFilterMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringInPlaceIndicator>(), //
        make_unique<ReadOzoneFilterMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringGeneratedCommandList>(), //
        make_unique<ReadOzoneFilterMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringAcceptedCommandList>(), //
        make_unique<ReadOzoneFilterMonitoringEventList>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringEventList>(), //
        make_unique<ReadOzoneFilterMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringAttributeList>(), //
        make_unique<ReadOzoneFilterMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringFeatureMap>(), //
        make_unique<ReadOzoneFilterMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeOzoneFilterMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterWaterTankMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::WaterTankMonitoring;

    const char * clusterName = "WaterTankMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<WaterTankMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadWaterTankMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeWaterTankMonitoringCondition>(), //
        make_unique<ReadWaterTankMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringDegradationDirection>(), //
        make_unique<ReadWaterTankMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringChangeIndication>(), //
        make_unique<ReadWaterTankMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringInPlaceIndicator>(), //
        make_unique<ReadWaterTankMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringGeneratedCommandList>(), //
        make_unique<ReadWaterTankMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringAcceptedCommandList>(), //
        make_unique<ReadWaterTankMonitoringEventList>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringEventList>(), //
        make_unique<ReadWaterTankMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringAttributeList>(), //
        make_unique<ReadWaterTankMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringFeatureMap>(), //
        make_unique<ReadWaterTankMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeWaterTankMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterFuelTankMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::FuelTankMonitoring;

    const char * clusterName = "FuelTankMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<FuelTankMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadFuelTankMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeFuelTankMonitoringCondition>(), //
        make_unique<ReadFuelTankMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringDegradationDirection>(), //
        make_unique<ReadFuelTankMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringChangeIndication>(), //
        make_unique<ReadFuelTankMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringInPlaceIndicator>(), //
        make_unique<ReadFuelTankMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringGeneratedCommandList>(), //
        make_unique<ReadFuelTankMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringAcceptedCommandList>(), //
        make_unique<ReadFuelTankMonitoringEventList>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringEventList>(), //
        make_unique<ReadFuelTankMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringAttributeList>(), //
        make_unique<ReadFuelTankMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringFeatureMap>(), //
        make_unique<ReadFuelTankMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeFuelTankMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterInkCartridgeMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::InkCartridgeMonitoring;

    const char * clusterName = "InkCartridgeMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<InkCartridgeMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadInkCartridgeMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringCondition>(), //
        make_unique<ReadInkCartridgeMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringDegradationDirection>(), //
        make_unique<ReadInkCartridgeMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringChangeIndication>(), //
        make_unique<ReadInkCartridgeMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringInPlaceIndicator>(), //
        make_unique<ReadInkCartridgeMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringGeneratedCommandList>(), //
        make_unique<ReadInkCartridgeMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringAcceptedCommandList>(), //
        make_unique<ReadInkCartridgeMonitoringEventList>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringEventList>(), //
        make_unique<ReadInkCartridgeMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringAttributeList>(), //
        make_unique<ReadInkCartridgeMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringFeatureMap>(), //
        make_unique<ReadInkCartridgeMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeInkCartridgeMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterTonerCartridgeMonitoring(Commands & commands)
{
    using namespace chip::app::Clusters::TonerCartridgeMonitoring;

    const char * clusterName = "TonerCartridgeMonitoring";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<TonerCartridgeMonitoringResetCondition>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadTonerCartridgeMonitoringCondition>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringCondition>(), //
        make_unique<ReadTonerCartridgeMonitoringDegradationDirection>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringDegradationDirection>(), //
        make_unique<ReadTonerCartridgeMonitoringChangeIndication>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringChangeIndication>(), //
        make_unique<ReadTonerCartridgeMonitoringInPlaceIndicator>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringInPlaceIndicator>(), //
        make_unique<ReadTonerCartridgeMonitoringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringGeneratedCommandList>(), //
        make_unique<ReadTonerCartridgeMonitoringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringAcceptedCommandList>(), //
        make_unique<ReadTonerCartridgeMonitoringEventList>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringEventList>(), //
        make_unique<ReadTonerCartridgeMonitoringAttributeList>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringAttributeList>(), //
        make_unique<ReadTonerCartridgeMonitoringFeatureMap>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringFeatureMap>(), //
        make_unique<ReadTonerCartridgeMonitoringClusterRevision>(), //
        make_unique<SubscribeAttributeTonerCartridgeMonitoringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterDoorLock(Commands & commands)
{
    using namespace chip::app::Clusters::DoorLock;

    const char * clusterName = "DoorLock";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<DoorLockLockDoor>(), //
        make_unique<DoorLockUnlockDoor>(), //
        make_unique<DoorLockUnlockWithTimeout>(), //
        make_unique<DoorLockSetWeekDaySchedule>(), //
        make_unique<DoorLockGetWeekDaySchedule>(), //
        make_unique<DoorLockClearWeekDaySchedule>(), //
        make_unique<DoorLockSetYearDaySchedule>(), //
        make_unique<DoorLockGetYearDaySchedule>(), //
        make_unique<DoorLockClearYearDaySchedule>(), //
        make_unique<DoorLockSetHolidaySchedule>(), //
        make_unique<DoorLockGetHolidaySchedule>(), //
        make_unique<DoorLockClearHolidaySchedule>(), //
        make_unique<DoorLockSetUser>(), //
        make_unique<DoorLockGetUser>(), //
        make_unique<DoorLockClearUser>(), //
        make_unique<DoorLockSetCredential>(), //
        make_unique<DoorLockGetCredentialStatus>(), //
        make_unique<DoorLockClearCredential>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadDoorLockLockState>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeDoorLockLockState>(), //
        make_unique<ReadDoorLockLockType>(), //
        make_unique<SubscribeAttributeDoorLockLockType>(), //
        make_unique<ReadDoorLockActuatorEnabled>(), //
        make_unique<SubscribeAttributeDoorLockActuatorEnabled>(), //
        make_unique<ReadDoorLockDoorState>(), //
        make_unique<SubscribeAttributeDoorLockDoorState>(), //
        make_unique<ReadDoorLockDoorOpenEvents>(), //
        make_unique<WriteDoorLockDoorOpenEvents>(), //
        make_unique<SubscribeAttributeDoorLockDoorOpenEvents>(), //
        make_unique<ReadDoorLockDoorClosedEvents>(), //
        make_unique<WriteDoorLockDoorClosedEvents>(), //
        make_unique<SubscribeAttributeDoorLockDoorClosedEvents>(), //
        make_unique<ReadDoorLockOpenPeriod>(), //
        make_unique<WriteDoorLockOpenPeriod>(), //
        make_unique<SubscribeAttributeDoorLockOpenPeriod>(), //
        make_unique<ReadDoorLockNumberOfTotalUsersSupported>(), //
        make_unique<SubscribeAttributeDoorLockNumberOfTotalUsersSupported>(), //
        make_unique<ReadDoorLockNumberOfPINUsersSupported>(), //
        make_unique<SubscribeAttributeDoorLockNumberOfPINUsersSupported>(), //
        make_unique<ReadDoorLockNumberOfRFIDUsersSupported>(), //
        make_unique<SubscribeAttributeDoorLockNumberOfRFIDUsersSupported>(), //
        make_unique<ReadDoorLockNumberOfWeekDaySchedulesSupportedPerUser>(), //
        make_unique<SubscribeAttributeDoorLockNumberOfWeekDaySchedulesSupportedPerUser>(), //
        make_unique<ReadDoorLockNumberOfYearDaySchedulesSupportedPerUser>(), //
        make_unique<SubscribeAttributeDoorLockNumberOfYearDaySchedulesSupportedPerUser>(), //
        make_unique<ReadDoorLockNumberOfHolidaySchedulesSupported>(), //
        make_unique<SubscribeAttributeDoorLockNumberOfHolidaySchedulesSupported>(), //
        make_unique<ReadDoorLockMaxPINCodeLength>(), //
        make_unique<SubscribeAttributeDoorLockMaxPINCodeLength>(), //
        make_unique<ReadDoorLockMinPINCodeLength>(), //
        make_unique<SubscribeAttributeDoorLockMinPINCodeLength>(), //
        make_unique<ReadDoorLockMaxRFIDCodeLength>(), //
        make_unique<SubscribeAttributeDoorLockMaxRFIDCodeLength>(), //
        make_unique<ReadDoorLockMinRFIDCodeLength>(), //
        make_unique<SubscribeAttributeDoorLockMinRFIDCodeLength>(), //
        make_unique<ReadDoorLockCredentialRulesSupport>(), //
        make_unique<SubscribeAttributeDoorLockCredentialRulesSupport>(), //
        make_unique<ReadDoorLockNumberOfCredentialsSupportedPerUser>(), //
        make_unique<SubscribeAttributeDoorLockNumberOfCredentialsSupportedPerUser>(), //
        make_unique<ReadDoorLockLanguage>(), //
        make_unique<WriteDoorLockLanguage>(), //
        make_unique<SubscribeAttributeDoorLockLanguage>(), //
        make_unique<ReadDoorLockLEDSettings>(), //
        make_unique<WriteDoorLockLEDSettings>(), //
        make_unique<SubscribeAttributeDoorLockLEDSettings>(), //
        make_unique<ReadDoorLockAutoRelockTime>(), //
        make_unique<WriteDoorLockAutoRelockTime>(), //
        make_unique<SubscribeAttributeDoorLockAutoRelockTime>(), //
        make_unique<ReadDoorLockSoundVolume>(), //
        make_unique<WriteDoorLockSoundVolume>(), //
        make_unique<SubscribeAttributeDoorLockSoundVolume>(), //
        make_unique<ReadDoorLockOperatingMode>(), //
        make_unique<WriteDoorLockOperatingMode>(), //
        make_unique<SubscribeAttributeDoorLockOperatingMode>(), //
        make_unique<ReadDoorLockSupportedOperatingModes>(), //
        make_unique<SubscribeAttributeDoorLockSupportedOperatingModes>(), //
        make_unique<ReadDoorLockDefaultConfigurationRegister>(), //
        make_unique<SubscribeAttributeDoorLockDefaultConfigurationRegister>(), //
        make_unique<ReadDoorLockEnableLocalProgramming>(), //
        make_unique<WriteDoorLockEnableLocalProgramming>(), //
        make_unique<SubscribeAttributeDoorLockEnableLocalProgramming>(), //
        make_unique<ReadDoorLockEnableOneTouchLocking>(), //
        make_unique<WriteDoorLockEnableOneTouchLocking>(), //
        make_unique<SubscribeAttributeDoorLockEnableOneTouchLocking>(), //
        make_unique<ReadDoorLockEnableInsideStatusLED>(), //
        make_unique<WriteDoorLockEnableInsideStatusLED>(), //
        make_unique<SubscribeAttributeDoorLockEnableInsideStatusLED>(), //
        make_unique<ReadDoorLockEnablePrivacyModeButton>(), //
        make_unique<WriteDoorLockEnablePrivacyModeButton>(), //
        make_unique<SubscribeAttributeDoorLockEnablePrivacyModeButton>(), //
        make_unique<ReadDoorLockLocalProgrammingFeatures>(), //
        make_unique<WriteDoorLockLocalProgrammingFeatures>(), //
        make_unique<SubscribeAttributeDoorLockLocalProgrammingFeatures>(), //
        make_unique<ReadDoorLockWrongCodeEntryLimit>(), //
        make_unique<WriteDoorLockWrongCodeEntryLimit>(), //
        make_unique<SubscribeAttributeDoorLockWrongCodeEntryLimit>(), //
        make_unique<ReadDoorLockUserCodeTemporaryDisableTime>(), //
        make_unique<WriteDoorLockUserCodeTemporaryDisableTime>(), //
        make_unique<SubscribeAttributeDoorLockUserCodeTemporaryDisableTime>(), //
        make_unique<ReadDoorLockSendPINOverTheAir>(), //
        make_unique<WriteDoorLockSendPINOverTheAir>(), //
        make_unique<SubscribeAttributeDoorLockSendPINOverTheAir>(), //
        make_unique<ReadDoorLockRequirePINforRemoteOperation>(), //
        make_unique<WriteDoorLockRequirePINforRemoteOperation>(), //
        make_unique<SubscribeAttributeDoorLockRequirePINforRemoteOperation>(), //
        make_unique<ReadDoorLockExpiringUserTimeout>(), //
        make_unique<WriteDoorLockExpiringUserTimeout>(), //
        make_unique<SubscribeAttributeDoorLockExpiringUserTimeout>(), //
        make_unique<ReadDoorLockGeneratedCommandList>(), //
        make_unique<SubscribeAttributeDoorLockGeneratedCommandList>(), //
        make_unique<ReadDoorLockAcceptedCommandList>(), //
        make_unique<SubscribeAttributeDoorLockAcceptedCommandList>(), //
        make_unique<ReadDoorLockAttributeList>(), //
        make_unique<SubscribeAttributeDoorLockAttributeList>(), //
        make_unique<ReadDoorLockFeatureMap>(), //
        make_unique<SubscribeAttributeDoorLockFeatureMap>(), //
        make_unique<ReadDoorLockClusterRevision>(), //
        make_unique<SubscribeAttributeDoorLockClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterWindowCovering(Commands & commands)
{
    using namespace chip::app::Clusters::WindowCovering;

    const char * clusterName = "WindowCovering";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<WindowCoveringUpOrOpen>(), //
        make_unique<WindowCoveringDownOrClose>(), //
        make_unique<WindowCoveringStopMotion>(), //
        make_unique<WindowCoveringGoToLiftValue>(), //
        make_unique<WindowCoveringGoToLiftPercentage>(), //
        make_unique<WindowCoveringGoToTiltValue>(), //
        make_unique<WindowCoveringGoToTiltPercentage>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadWindowCoveringType>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeWindowCoveringType>(), //
        make_unique<ReadWindowCoveringPhysicalClosedLimitLift>(), //
        make_unique<SubscribeAttributeWindowCoveringPhysicalClosedLimitLift>(), //
        make_unique<ReadWindowCoveringPhysicalClosedLimitTilt>(), //
        make_unique<SubscribeAttributeWindowCoveringPhysicalClosedLimitTilt>(), //
        make_unique<ReadWindowCoveringCurrentPositionLift>(), //
        make_unique<SubscribeAttributeWindowCoveringCurrentPositionLift>(), //
        make_unique<ReadWindowCoveringCurrentPositionTilt>(), //
        make_unique<SubscribeAttributeWindowCoveringCurrentPositionTilt>(), //
        make_unique<ReadWindowCoveringNumberOfActuationsLift>(), //
        make_unique<SubscribeAttributeWindowCoveringNumberOfActuationsLift>(), //
        make_unique<ReadWindowCoveringNumberOfActuationsTilt>(), //
        make_unique<SubscribeAttributeWindowCoveringNumberOfActuationsTilt>(), //
        make_unique<ReadWindowCoveringConfigStatus>(), //
        make_unique<SubscribeAttributeWindowCoveringConfigStatus>(), //
        make_unique<ReadWindowCoveringCurrentPositionLiftPercentage>(), //
        make_unique<SubscribeAttributeWindowCoveringCurrentPositionLiftPercentage>(), //
        make_unique<ReadWindowCoveringCurrentPositionTiltPercentage>(), //
        make_unique<SubscribeAttributeWindowCoveringCurrentPositionTiltPercentage>(), //
        make_unique<ReadWindowCoveringOperationalStatus>(), //
        make_unique<SubscribeAttributeWindowCoveringOperationalStatus>(), //
        make_unique<ReadWindowCoveringTargetPositionLiftPercent100ths>(), //
        make_unique<SubscribeAttributeWindowCoveringTargetPositionLiftPercent100ths>(), //
        make_unique<ReadWindowCoveringTargetPositionTiltPercent100ths>(), //
        make_unique<SubscribeAttributeWindowCoveringTargetPositionTiltPercent100ths>(), //
        make_unique<ReadWindowCoveringEndProductType>(), //
        make_unique<SubscribeAttributeWindowCoveringEndProductType>(), //
        make_unique<ReadWindowCoveringCurrentPositionLiftPercent100ths>(), //
        make_unique<SubscribeAttributeWindowCoveringCurrentPositionLiftPercent100ths>(), //
        make_unique<ReadWindowCoveringCurrentPositionTiltPercent100ths>(), //
        make_unique<SubscribeAttributeWindowCoveringCurrentPositionTiltPercent100ths>(), //
        make_unique<ReadWindowCoveringInstalledOpenLimitLift>(), //
        make_unique<SubscribeAttributeWindowCoveringInstalledOpenLimitLift>(), //
        make_unique<ReadWindowCoveringInstalledClosedLimitLift>(), //
        make_unique<SubscribeAttributeWindowCoveringInstalledClosedLimitLift>(), //
        make_unique<ReadWindowCoveringInstalledOpenLimitTilt>(), //
        make_unique<SubscribeAttributeWindowCoveringInstalledOpenLimitTilt>(), //
        make_unique<ReadWindowCoveringInstalledClosedLimitTilt>(), //
        make_unique<SubscribeAttributeWindowCoveringInstalledClosedLimitTilt>(), //
        make_unique<ReadWindowCoveringMode>(), //
        make_unique<WriteWindowCoveringMode>(), //
        make_unique<SubscribeAttributeWindowCoveringMode>(), //
        make_unique<ReadWindowCoveringSafetyStatus>(), //
        make_unique<SubscribeAttributeWindowCoveringSafetyStatus>(), //
        make_unique<ReadWindowCoveringGeneratedCommandList>(), //
        make_unique<SubscribeAttributeWindowCoveringGeneratedCommandList>(), //
        make_unique<ReadWindowCoveringAcceptedCommandList>(), //
        make_unique<SubscribeAttributeWindowCoveringAcceptedCommandList>(), //
        make_unique<ReadWindowCoveringAttributeList>(), //
        make_unique<SubscribeAttributeWindowCoveringAttributeList>(), //
        make_unique<ReadWindowCoveringFeatureMap>(), //
        make_unique<SubscribeAttributeWindowCoveringFeatureMap>(), //
        make_unique<ReadWindowCoveringClusterRevision>(), //
        make_unique<SubscribeAttributeWindowCoveringClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterBarrierControl(Commands & commands)
{
    using namespace chip::app::Clusters::BarrierControl;

    const char * clusterName = "BarrierControl";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<BarrierControlBarrierControlGoToPercent>(), //
        make_unique<BarrierControlBarrierControlStop>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadBarrierControlBarrierMovingState>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeBarrierControlBarrierMovingState>(), //
        make_unique<ReadBarrierControlBarrierSafetyStatus>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierSafetyStatus>(), //
        make_unique<ReadBarrierControlBarrierCapabilities>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierCapabilities>(), //
        make_unique<ReadBarrierControlBarrierOpenEvents>(), //
        make_unique<WriteBarrierControlBarrierOpenEvents>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierOpenEvents>(), //
        make_unique<ReadBarrierControlBarrierCloseEvents>(), //
        make_unique<WriteBarrierControlBarrierCloseEvents>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierCloseEvents>(), //
        make_unique<ReadBarrierControlBarrierCommandOpenEvents>(), //
        make_unique<WriteBarrierControlBarrierCommandOpenEvents>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierCommandOpenEvents>(), //
        make_unique<ReadBarrierControlBarrierCommandCloseEvents>(), //
        make_unique<WriteBarrierControlBarrierCommandCloseEvents>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierCommandCloseEvents>(), //
        make_unique<ReadBarrierControlBarrierOpenPeriod>(), //
        make_unique<WriteBarrierControlBarrierOpenPeriod>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierOpenPeriod>(), //
        make_unique<ReadBarrierControlBarrierClosePeriod>(), //
        make_unique<WriteBarrierControlBarrierClosePeriod>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierClosePeriod>(), //
        make_unique<ReadBarrierControlBarrierPosition>(), //
        make_unique<SubscribeAttributeBarrierControlBarrierPosition>(), //
        make_unique<ReadBarrierControlGeneratedCommandList>(), //
        make_unique<SubscribeAttributeBarrierControlGeneratedCommandList>(), //
        make_unique<ReadBarrierControlAcceptedCommandList>(), //
        make_unique<SubscribeAttributeBarrierControlAcceptedCommandList>(), //
        make_unique<ReadBarrierControlAttributeList>(), //
        make_unique<SubscribeAttributeBarrierControlAttributeList>(), //
        make_unique<ReadBarrierControlFeatureMap>(), //
        make_unique<SubscribeAttributeBarrierControlFeatureMap>(), //
        make_unique<ReadBarrierControlClusterRevision>(), //
        make_unique<SubscribeAttributeBarrierControlClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterPumpConfigurationAndControl(Commands & commands)
{
    using namespace chip::app::Clusters::PumpConfigurationAndControl;

    const char * clusterName = "PumpConfigurationAndControl";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadPumpConfigurationAndControlMaxPressure>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxPressure>(), //
        make_unique<ReadPumpConfigurationAndControlMaxSpeed>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxSpeed>(), //
        make_unique<ReadPumpConfigurationAndControlMaxFlow>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxFlow>(), //
        make_unique<ReadPumpConfigurationAndControlMinConstPressure>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMinConstPressure>(), //
        make_unique<ReadPumpConfigurationAndControlMaxConstPressure>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxConstPressure>(), //
        make_unique<ReadPumpConfigurationAndControlMinCompPressure>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMinCompPressure>(), //
        make_unique<ReadPumpConfigurationAndControlMaxCompPressure>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxCompPressure>(), //
        make_unique<ReadPumpConfigurationAndControlMinConstSpeed>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMinConstSpeed>(), //
        make_unique<ReadPumpConfigurationAndControlMaxConstSpeed>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxConstSpeed>(), //
        make_unique<ReadPumpConfigurationAndControlMinConstFlow>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMinConstFlow>(), //
        make_unique<ReadPumpConfigurationAndControlMaxConstFlow>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxConstFlow>(), //
        make_unique<ReadPumpConfigurationAndControlMinConstTemp>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMinConstTemp>(), //
        make_unique<ReadPumpConfigurationAndControlMaxConstTemp>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlMaxConstTemp>(), //
        make_unique<ReadPumpConfigurationAndControlPumpStatus>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlPumpStatus>(), //
        make_unique<ReadPumpConfigurationAndControlEffectiveOperationMode>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlEffectiveOperationMode>(), //
        make_unique<ReadPumpConfigurationAndControlEffectiveControlMode>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlEffectiveControlMode>(), //
        make_unique<ReadPumpConfigurationAndControlCapacity>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlCapacity>(), //
        make_unique<ReadPumpConfigurationAndControlSpeed>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlSpeed>(), //
        make_unique<ReadPumpConfigurationAndControlLifetimeRunningHours>(), //
        make_unique<WritePumpConfigurationAndControlLifetimeRunningHours>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlLifetimeRunningHours>(), //
        make_unique<ReadPumpConfigurationAndControlPower>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlPower>(), //
        make_unique<ReadPumpConfigurationAndControlLifetimeEnergyConsumed>(), //
        make_unique<WritePumpConfigurationAndControlLifetimeEnergyConsumed>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlLifetimeEnergyConsumed>(), //
        make_unique<ReadPumpConfigurationAndControlOperationMode>(), //
        make_unique<WritePumpConfigurationAndControlOperationMode>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlOperationMode>(), //
        make_unique<ReadPumpConfigurationAndControlControlMode>(), //
        make_unique<WritePumpConfigurationAndControlControlMode>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlControlMode>(), //
        make_unique<ReadPumpConfigurationAndControlGeneratedCommandList>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlGeneratedCommandList>(), //
        make_unique<ReadPumpConfigurationAndControlAcceptedCommandList>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlAcceptedCommandList>(), //
        make_unique<ReadPumpConfigurationAndControlAttributeList>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlAttributeList>(), //
        make_unique<ReadPumpConfigurationAndControlFeatureMap>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlFeatureMap>(), //
        make_unique<ReadPumpConfigurationAndControlClusterRevision>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterThermostat(Commands & commands)
{
    using namespace chip::app::Clusters::Thermostat;

    const char * clusterName = "Thermostat";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ThermostatSetpointRaiseLower>(), //
        make_unique<ThermostatSetWeeklySchedule>(), //
        make_unique<ThermostatGetWeeklySchedule>(), //
        make_unique<ThermostatClearWeeklySchedule>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadThermostatLocalTemperature>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeThermostatLocalTemperature>(), //
        make_unique<ReadThermostatOutdoorTemperature>(), //
        make_unique<SubscribeAttributeThermostatOutdoorTemperature>(), //
        make_unique<ReadThermostatOccupancy>(), //
        make_unique<SubscribeAttributeThermostatOccupancy>(), //
        make_unique<ReadThermostatAbsMinHeatSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatAbsMinHeatSetpointLimit>(), //
        make_unique<ReadThermostatAbsMaxHeatSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatAbsMaxHeatSetpointLimit>(), //
        make_unique<ReadThermostatAbsMinCoolSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatAbsMinCoolSetpointLimit>(), //
        make_unique<ReadThermostatAbsMaxCoolSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatAbsMaxCoolSetpointLimit>(), //
        make_unique<ReadThermostatPICoolingDemand>(), //
        make_unique<SubscribeAttributeThermostatPICoolingDemand>(), //
        make_unique<ReadThermostatPIHeatingDemand>(), //
        make_unique<SubscribeAttributeThermostatPIHeatingDemand>(), //
        make_unique<ReadThermostatHVACSystemTypeConfiguration>(), //
        make_unique<WriteThermostatHVACSystemTypeConfiguration>(), //
        make_unique<SubscribeAttributeThermostatHVACSystemTypeConfiguration>(), //
        make_unique<ReadThermostatLocalTemperatureCalibration>(), //
        make_unique<WriteThermostatLocalTemperatureCalibration>(), //
        make_unique<SubscribeAttributeThermostatLocalTemperatureCalibration>(), //
        make_unique<ReadThermostatOccupiedCoolingSetpoint>(), //
        make_unique<WriteThermostatOccupiedCoolingSetpoint>(), //
        make_unique<SubscribeAttributeThermostatOccupiedCoolingSetpoint>(), //
        make_unique<ReadThermostatOccupiedHeatingSetpoint>(), //
        make_unique<WriteThermostatOccupiedHeatingSetpoint>(), //
        make_unique<SubscribeAttributeThermostatOccupiedHeatingSetpoint>(), //
        make_unique<ReadThermostatUnoccupiedCoolingSetpoint>(), //
        make_unique<WriteThermostatUnoccupiedCoolingSetpoint>(), //
        make_unique<SubscribeAttributeThermostatUnoccupiedCoolingSetpoint>(), //
        make_unique<ReadThermostatUnoccupiedHeatingSetpoint>(), //
        make_unique<WriteThermostatUnoccupiedHeatingSetpoint>(), //
        make_unique<SubscribeAttributeThermostatUnoccupiedHeatingSetpoint>(), //
        make_unique<ReadThermostatMinHeatSetpointLimit>(), //
        make_unique<WriteThermostatMinHeatSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatMinHeatSetpointLimit>(), //
        make_unique<ReadThermostatMaxHeatSetpointLimit>(), //
        make_unique<WriteThermostatMaxHeatSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatMaxHeatSetpointLimit>(), //
        make_unique<ReadThermostatMinCoolSetpointLimit>(), //
        make_unique<WriteThermostatMinCoolSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatMinCoolSetpointLimit>(), //
        make_unique<ReadThermostatMaxCoolSetpointLimit>(), //
        make_unique<WriteThermostatMaxCoolSetpointLimit>(), //
        make_unique<SubscribeAttributeThermostatMaxCoolSetpointLimit>(), //
        make_unique<ReadThermostatMinSetpointDeadBand>(), //
        make_unique<WriteThermostatMinSetpointDeadBand>(), //
        make_unique<SubscribeAttributeThermostatMinSetpointDeadBand>(), //
        make_unique<ReadThermostatRemoteSensing>(), //
        make_unique<WriteThermostatRemoteSensing>(), //
        make_unique<SubscribeAttributeThermostatRemoteSensing>(), //
        make_unique<ReadThermostatControlSequenceOfOperation>(), //
        make_unique<WriteThermostatControlSequenceOfOperation>(), //
        make_unique<SubscribeAttributeThermostatControlSequenceOfOperation>(), //
        make_unique<ReadThermostatSystemMode>(), //
        make_unique<WriteThermostatSystemMode>(), //
        make_unique<SubscribeAttributeThermostatSystemMode>(), //
        make_unique<ReadThermostatThermostatRunningMode>(), //
        make_unique<SubscribeAttributeThermostatThermostatRunningMode>(), //
        make_unique<ReadThermostatStartOfWeek>(), //
        make_unique<SubscribeAttributeThermostatStartOfWeek>(), //
        make_unique<ReadThermostatNumberOfWeeklyTransitions>(), //
        make_unique<SubscribeAttributeThermostatNumberOfWeeklyTransitions>(), //
        make_unique<ReadThermostatNumberOfDailyTransitions>(), //
        make_unique<SubscribeAttributeThermostatNumberOfDailyTransitions>(), //
        make_unique<ReadThermostatTemperatureSetpointHold>(), //
        make_unique<WriteThermostatTemperatureSetpointHold>(), //
        make_unique<SubscribeAttributeThermostatTemperatureSetpointHold>(), //
        make_unique<ReadThermostatTemperatureSetpointHoldDuration>(), //
        make_unique<WriteThermostatTemperatureSetpointHoldDuration>(), //
        make_unique<SubscribeAttributeThermostatTemperatureSetpointHoldDuration>(), //
        make_unique<ReadThermostatThermostatProgrammingOperationMode>(), //
        make_unique<WriteThermostatThermostatProgrammingOperationMode>(), //
        make_unique<SubscribeAttributeThermostatThermostatProgrammingOperationMode>(), //
        make_unique<ReadThermostatThermostatRunningState>(), //
        make_unique<SubscribeAttributeThermostatThermostatRunningState>(), //
        make_unique<ReadThermostatSetpointChangeSource>(), //
        make_unique<SubscribeAttributeThermostatSetpointChangeSource>(), //
        make_unique<ReadThermostatSetpointChangeAmount>(), //
        make_unique<SubscribeAttributeThermostatSetpointChangeAmount>(), //
        make_unique<ReadThermostatSetpointChangeSourceTimestamp>(), //
        make_unique<SubscribeAttributeThermostatSetpointChangeSourceTimestamp>(), //
        make_unique<ReadThermostatOccupiedSetback>(), //
        make_unique<WriteThermostatOccupiedSetback>(), //
        make_unique<SubscribeAttributeThermostatOccupiedSetback>(), //
        make_unique<ReadThermostatOccupiedSetbackMin>(), //
        make_unique<SubscribeAttributeThermostatOccupiedSetbackMin>(), //
        make_unique<ReadThermostatOccupiedSetbackMax>(), //
        make_unique<SubscribeAttributeThermostatOccupiedSetbackMax>(), //
        make_unique<ReadThermostatUnoccupiedSetback>(), //
        make_unique<WriteThermostatUnoccupiedSetback>(), //
        make_unique<SubscribeAttributeThermostatUnoccupiedSetback>(), //
        make_unique<ReadThermostatUnoccupiedSetbackMin>(), //
        make_unique<SubscribeAttributeThermostatUnoccupiedSetbackMin>(), //
        make_unique<ReadThermostatUnoccupiedSetbackMax>(), //
        make_unique<SubscribeAttributeThermostatUnoccupiedSetbackMax>(), //
        make_unique<ReadThermostatEmergencyHeatDelta>(), //
        make_unique<WriteThermostatEmergencyHeatDelta>(), //
        make_unique<SubscribeAttributeThermostatEmergencyHeatDelta>(), //
        make_unique<ReadThermostatACType>(), //
        make_unique<WriteThermostatACType>(), //
        make_unique<SubscribeAttributeThermostatACType>(), //
        make_unique<ReadThermostatACCapacity>(), //
        make_unique<WriteThermostatACCapacity>(), //
        make_unique<SubscribeAttributeThermostatACCapacity>(), //
        make_unique<ReadThermostatACRefrigerantType>(), //
        make_unique<WriteThermostatACRefrigerantType>(), //
        make_unique<SubscribeAttributeThermostatACRefrigerantType>(), //
        make_unique<ReadThermostatACCompressorType>(), //
        make_unique<WriteThermostatACCompressorType>(), //
        make_unique<SubscribeAttributeThermostatACCompressorType>(), //
        make_unique<ReadThermostatACErrorCode>(), //
        make_unique<WriteThermostatACErrorCode>(), //
        make_unique<SubscribeAttributeThermostatACErrorCode>(), //
        make_unique<ReadThermostatACLouverPosition>(), //
        make_unique<WriteThermostatACLouverPosition>(), //
        make_unique<SubscribeAttributeThermostatACLouverPosition>(), //
        make_unique<ReadThermostatACCoilTemperature>(), //
        make_unique<SubscribeAttributeThermostatACCoilTemperature>(), //
        make_unique<ReadThermostatACCapacityformat>(), //
        make_unique<WriteThermostatACCapacityformat>(), //
        make_unique<SubscribeAttributeThermostatACCapacityformat>(), //
        make_unique<ReadThermostatGeneratedCommandList>(), //
        make_unique<SubscribeAttributeThermostatGeneratedCommandList>(), //
        make_unique<ReadThermostatAcceptedCommandList>(), //
        make_unique<SubscribeAttributeThermostatAcceptedCommandList>(), //
        make_unique<ReadThermostatAttributeList>(), //
        make_unique<SubscribeAttributeThermostatAttributeList>(), //
        make_unique<ReadThermostatFeatureMap>(), //
        make_unique<SubscribeAttributeThermostatFeatureMap>(), //
        make_unique<ReadThermostatClusterRevision>(), //
        make_unique<SubscribeAttributeThermostatClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterFanControl(Commands & commands)
{
    using namespace chip::app::Clusters::FanControl;

    const char * clusterName = "FanControl";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadFanControlFanMode>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteFanControlFanMode>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeFanControlFanMode>(), //
        make_unique<ReadFanControlFanModeSequence>(), //
        make_unique<WriteFanControlFanModeSequence>(), //
        make_unique<SubscribeAttributeFanControlFanModeSequence>(), //
        make_unique<ReadFanControlPercentSetting>(), //
        make_unique<WriteFanControlPercentSetting>(), //
        make_unique<SubscribeAttributeFanControlPercentSetting>(), //
        make_unique<ReadFanControlPercentCurrent>(), //
        make_unique<SubscribeAttributeFanControlPercentCurrent>(), //
        make_unique<ReadFanControlSpeedMax>(), //
        make_unique<SubscribeAttributeFanControlSpeedMax>(), //
        make_unique<ReadFanControlSpeedSetting>(), //
        make_unique<WriteFanControlSpeedSetting>(), //
        make_unique<SubscribeAttributeFanControlSpeedSetting>(), //
        make_unique<ReadFanControlSpeedCurrent>(), //
        make_unique<SubscribeAttributeFanControlSpeedCurrent>(), //
        make_unique<ReadFanControlRockSupport>(), //
        make_unique<SubscribeAttributeFanControlRockSupport>(), //
        make_unique<ReadFanControlRockSetting>(), //
        make_unique<WriteFanControlRockSetting>(), //
        make_unique<SubscribeAttributeFanControlRockSetting>(), //
        make_unique<ReadFanControlWindSupport>(), //
        make_unique<SubscribeAttributeFanControlWindSupport>(), //
        make_unique<ReadFanControlWindSetting>(), //
        make_unique<WriteFanControlWindSetting>(), //
        make_unique<SubscribeAttributeFanControlWindSetting>(), //
        make_unique<ReadFanControlGeneratedCommandList>(), //
        make_unique<SubscribeAttributeFanControlGeneratedCommandList>(), //
        make_unique<ReadFanControlAcceptedCommandList>(), //
        make_unique<SubscribeAttributeFanControlAcceptedCommandList>(), //
        make_unique<ReadFanControlAttributeList>(), //
        make_unique<SubscribeAttributeFanControlAttributeList>(), //
        make_unique<ReadFanControlFeatureMap>(), //
        make_unique<SubscribeAttributeFanControlFeatureMap>(), //
        make_unique<ReadFanControlClusterRevision>(), //
        make_unique<SubscribeAttributeFanControlClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterThermostatUserInterfaceConfiguration(Commands & commands)
{
    using namespace chip::app::Clusters::ThermostatUserInterfaceConfiguration;

    const char * clusterName = "ThermostatUserInterfaceConfiguration";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadThermostatUserInterfaceConfigurationTemperatureDisplayMode>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteThermostatUserInterfaceConfigurationTemperatureDisplayMode>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationTemperatureDisplayMode>(), //
        make_unique<ReadThermostatUserInterfaceConfigurationKeypadLockout>(), //
        make_unique<WriteThermostatUserInterfaceConfigurationKeypadLockout>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationKeypadLockout>(), //
        make_unique<ReadThermostatUserInterfaceConfigurationScheduleProgrammingVisibility>(), //
        make_unique<WriteThermostatUserInterfaceConfigurationScheduleProgrammingVisibility>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationScheduleProgrammingVisibility>(), //
        make_unique<ReadThermostatUserInterfaceConfigurationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationGeneratedCommandList>(), //
        make_unique<ReadThermostatUserInterfaceConfigurationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationAcceptedCommandList>(), //
        make_unique<ReadThermostatUserInterfaceConfigurationAttributeList>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationAttributeList>(), //
        make_unique<ReadThermostatUserInterfaceConfigurationFeatureMap>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationFeatureMap>(), //
        make_unique<ReadThermostatUserInterfaceConfigurationClusterRevision>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterColorControl(Commands & commands)
{
    using namespace chip::app::Clusters::ColorControl;

    const char * clusterName = "ColorControl";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ColorControlMoveToHue>(), //
        make_unique<ColorControlMoveHue>(), //
        make_unique<ColorControlStepHue>(), //
        make_unique<ColorControlMoveToSaturation>(), //
        make_unique<ColorControlMoveSaturation>(), //
        make_unique<ColorControlStepSaturation>(), //
        make_unique<ColorControlMoveToHueAndSaturation>(), //
        make_unique<ColorControlMoveToColor>(), //
        make_unique<ColorControlMoveColor>(), //
        make_unique<ColorControlStepColor>(), //
        make_unique<ColorControlMoveToColorTemperature>(), //
        make_unique<ColorControlEnhancedMoveToHue>(), //
        make_unique<ColorControlEnhancedMoveHue>(), //
        make_unique<ColorControlEnhancedStepHue>(), //
        make_unique<ColorControlEnhancedMoveToHueAndSaturation>(), //
        make_unique<ColorControlColorLoopSet>(), //
        make_unique<ColorControlStopMoveStep>(), //
        make_unique<ColorControlMoveColorTemperature>(), //
        make_unique<ColorControlStepColorTemperature>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadColorControlCurrentHue>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeColorControlCurrentHue>(), //
        make_unique<ReadColorControlCurrentSaturation>(), //
        make_unique<SubscribeAttributeColorControlCurrentSaturation>(), //
        make_unique<ReadColorControlRemainingTime>(), //
        make_unique<SubscribeAttributeColorControlRemainingTime>(), //
        make_unique<ReadColorControlCurrentX>(), //
        make_unique<SubscribeAttributeColorControlCurrentX>(), //
        make_unique<ReadColorControlCurrentY>(), //
        make_unique<SubscribeAttributeColorControlCurrentY>(), //
        make_unique<ReadColorControlDriftCompensation>(), //
        make_unique<SubscribeAttributeColorControlDriftCompensation>(), //
        make_unique<ReadColorControlCompensationText>(), //
        make_unique<SubscribeAttributeColorControlCompensationText>(), //
        make_unique<ReadColorControlColorTemperatureMireds>(), //
        make_unique<SubscribeAttributeColorControlColorTemperatureMireds>(), //
        make_unique<ReadColorControlColorMode>(), //
        make_unique<SubscribeAttributeColorControlColorMode>(), //
        make_unique<ReadColorControlOptions>(), //
        make_unique<WriteColorControlOptions>(), //
        make_unique<SubscribeAttributeColorControlOptions>(), //
        make_unique<ReadColorControlNumberOfPrimaries>(), //
        make_unique<SubscribeAttributeColorControlNumberOfPrimaries>(), //
        make_unique<ReadColorControlPrimary1X>(), //
        make_unique<SubscribeAttributeColorControlPrimary1X>(), //
        make_unique<ReadColorControlPrimary1Y>(), //
        make_unique<SubscribeAttributeColorControlPrimary1Y>(), //
        make_unique<ReadColorControlPrimary1Intensity>(), //
        make_unique<SubscribeAttributeColorControlPrimary1Intensity>(), //
        make_unique<ReadColorControlPrimary2X>(), //
        make_unique<SubscribeAttributeColorControlPrimary2X>(), //
        make_unique<ReadColorControlPrimary2Y>(), //
        make_unique<SubscribeAttributeColorControlPrimary2Y>(), //
        make_unique<ReadColorControlPrimary2Intensity>(), //
        make_unique<SubscribeAttributeColorControlPrimary2Intensity>(), //
        make_unique<ReadColorControlPrimary3X>(), //
        make_unique<SubscribeAttributeColorControlPrimary3X>(), //
        make_unique<ReadColorControlPrimary3Y>(), //
        make_unique<SubscribeAttributeColorControlPrimary3Y>(), //
        make_unique<ReadColorControlPrimary3Intensity>(), //
        make_unique<SubscribeAttributeColorControlPrimary3Intensity>(), //
        make_unique<ReadColorControlPrimary4X>(), //
        make_unique<SubscribeAttributeColorControlPrimary4X>(), //
        make_unique<ReadColorControlPrimary4Y>(), //
        make_unique<SubscribeAttributeColorControlPrimary4Y>(), //
        make_unique<ReadColorControlPrimary4Intensity>(), //
        make_unique<SubscribeAttributeColorControlPrimary4Intensity>(), //
        make_unique<ReadColorControlPrimary5X>(), //
        make_unique<SubscribeAttributeColorControlPrimary5X>(), //
        make_unique<ReadColorControlPrimary5Y>(), //
        make_unique<SubscribeAttributeColorControlPrimary5Y>(), //
        make_unique<ReadColorControlPrimary5Intensity>(), //
        make_unique<SubscribeAttributeColorControlPrimary5Intensity>(), //
        make_unique<ReadColorControlPrimary6X>(), //
        make_unique<SubscribeAttributeColorControlPrimary6X>(), //
        make_unique<ReadColorControlPrimary6Y>(), //
        make_unique<SubscribeAttributeColorControlPrimary6Y>(), //
        make_unique<ReadColorControlPrimary6Intensity>(), //
        make_unique<SubscribeAttributeColorControlPrimary6Intensity>(), //
        make_unique<ReadColorControlWhitePointX>(), //
        make_unique<WriteColorControlWhitePointX>(), //
        make_unique<SubscribeAttributeColorControlWhitePointX>(), //
        make_unique<ReadColorControlWhitePointY>(), //
        make_unique<WriteColorControlWhitePointY>(), //
        make_unique<SubscribeAttributeColorControlWhitePointY>(), //
        make_unique<ReadColorControlColorPointRX>(), //
        make_unique<WriteColorControlColorPointRX>(), //
        make_unique<SubscribeAttributeColorControlColorPointRX>(), //
        make_unique<ReadColorControlColorPointRY>(), //
        make_unique<WriteColorControlColorPointRY>(), //
        make_unique<SubscribeAttributeColorControlColorPointRY>(), //
        make_unique<ReadColorControlColorPointRIntensity>(), //
        make_unique<WriteColorControlColorPointRIntensity>(), //
        make_unique<SubscribeAttributeColorControlColorPointRIntensity>(), //
        make_unique<ReadColorControlColorPointGX>(), //
        make_unique<WriteColorControlColorPointGX>(), //
        make_unique<SubscribeAttributeColorControlColorPointGX>(), //
        make_unique<ReadColorControlColorPointGY>(), //
        make_unique<WriteColorControlColorPointGY>(), //
        make_unique<SubscribeAttributeColorControlColorPointGY>(), //
        make_unique<ReadColorControlColorPointGIntensity>(), //
        make_unique<WriteColorControlColorPointGIntensity>(), //
        make_unique<SubscribeAttributeColorControlColorPointGIntensity>(), //
        make_unique<ReadColorControlColorPointBX>(), //
        make_unique<WriteColorControlColorPointBX>(), //
        make_unique<SubscribeAttributeColorControlColorPointBX>(), //
        make_unique<ReadColorControlColorPointBY>(), //
        make_unique<WriteColorControlColorPointBY>(), //
        make_unique<SubscribeAttributeColorControlColorPointBY>(), //
        make_unique<ReadColorControlColorPointBIntensity>(), //
        make_unique<WriteColorControlColorPointBIntensity>(), //
        make_unique<SubscribeAttributeColorControlColorPointBIntensity>(), //
        make_unique<ReadColorControlEnhancedCurrentHue>(), //
        make_unique<SubscribeAttributeColorControlEnhancedCurrentHue>(), //
        make_unique<ReadColorControlEnhancedColorMode>(), //
        make_unique<SubscribeAttributeColorControlEnhancedColorMode>(), //
        make_unique<ReadColorControlColorLoopActive>(), //
        make_unique<SubscribeAttributeColorControlColorLoopActive>(), //
        make_unique<ReadColorControlColorLoopDirection>(), //
        make_unique<SubscribeAttributeColorControlColorLoopDirection>(), //
        make_unique<ReadColorControlColorLoopTime>(), //
        make_unique<SubscribeAttributeColorControlColorLoopTime>(), //
        make_unique<ReadColorControlColorLoopStartEnhancedHue>(), //
        make_unique<SubscribeAttributeColorControlColorLoopStartEnhancedHue>(), //
        make_unique<ReadColorControlColorLoopStoredEnhancedHue>(), //
        make_unique<SubscribeAttributeColorControlColorLoopStoredEnhancedHue>(), //
        make_unique<ReadColorControlColorCapabilities>(), //
        make_unique<SubscribeAttributeColorControlColorCapabilities>(), //
        make_unique<ReadColorControlColorTempPhysicalMinMireds>(), //
        make_unique<SubscribeAttributeColorControlColorTempPhysicalMinMireds>(), //
        make_unique<ReadColorControlColorTempPhysicalMaxMireds>(), //
        make_unique<SubscribeAttributeColorControlColorTempPhysicalMaxMireds>(), //
        make_unique<ReadColorControlCoupleColorTempToLevelMinMireds>(), //
        make_unique<SubscribeAttributeColorControlCoupleColorTempToLevelMinMireds>(), //
        make_unique<ReadColorControlStartUpColorTemperatureMireds>(), //
        make_unique<WriteColorControlStartUpColorTemperatureMireds>(), //
        make_unique<SubscribeAttributeColorControlStartUpColorTemperatureMireds>(), //
        make_unique<ReadColorControlGeneratedCommandList>(), //
        make_unique<SubscribeAttributeColorControlGeneratedCommandList>(), //
        make_unique<ReadColorControlAcceptedCommandList>(), //
        make_unique<SubscribeAttributeColorControlAcceptedCommandList>(), //
        make_unique<ReadColorControlAttributeList>(), //
        make_unique<SubscribeAttributeColorControlAttributeList>(), //
        make_unique<ReadColorControlFeatureMap>(), //
        make_unique<SubscribeAttributeColorControlFeatureMap>(), //
        make_unique<ReadColorControlClusterRevision>(), //
        make_unique<SubscribeAttributeColorControlClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterBallastConfiguration(Commands & commands)
{
    using namespace chip::app::Clusters::BallastConfiguration;

    const char * clusterName = "BallastConfiguration";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadBallastConfigurationPhysicalMinLevel>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeBallastConfigurationPhysicalMinLevel>(), //
        make_unique<ReadBallastConfigurationPhysicalMaxLevel>(), //
        make_unique<SubscribeAttributeBallastConfigurationPhysicalMaxLevel>(), //
        make_unique<ReadBallastConfigurationBallastStatus>(), //
        make_unique<SubscribeAttributeBallastConfigurationBallastStatus>(), //
        make_unique<ReadBallastConfigurationMinLevel>(), //
        make_unique<WriteBallastConfigurationMinLevel>(), //
        make_unique<SubscribeAttributeBallastConfigurationMinLevel>(), //
        make_unique<ReadBallastConfigurationMaxLevel>(), //
        make_unique<WriteBallastConfigurationMaxLevel>(), //
        make_unique<SubscribeAttributeBallastConfigurationMaxLevel>(), //
        make_unique<ReadBallastConfigurationIntrinsicBallastFactor>(), //
        make_unique<WriteBallastConfigurationIntrinsicBallastFactor>(), //
        make_unique<SubscribeAttributeBallastConfigurationIntrinsicBallastFactor>(), //
        make_unique<ReadBallastConfigurationBallastFactorAdjustment>(), //
        make_unique<WriteBallastConfigurationBallastFactorAdjustment>(), //
        make_unique<SubscribeAttributeBallastConfigurationBallastFactorAdjustment>(), //
        make_unique<ReadBallastConfigurationLampQuantity>(), //
        make_unique<SubscribeAttributeBallastConfigurationLampQuantity>(), //
        make_unique<ReadBallastConfigurationLampType>(), //
        make_unique<WriteBallastConfigurationLampType>(), //
        make_unique<SubscribeAttributeBallastConfigurationLampType>(), //
        make_unique<ReadBallastConfigurationLampManufacturer>(), //
        make_unique<WriteBallastConfigurationLampManufacturer>(), //
        make_unique<SubscribeAttributeBallastConfigurationLampManufacturer>(), //
        make_unique<ReadBallastConfigurationLampRatedHours>(), //
        make_unique<WriteBallastConfigurationLampRatedHours>(), //
        make_unique<SubscribeAttributeBallastConfigurationLampRatedHours>(), //
        make_unique<ReadBallastConfigurationLampBurnHours>(), //
        make_unique<WriteBallastConfigurationLampBurnHours>(), //
        make_unique<SubscribeAttributeBallastConfigurationLampBurnHours>(), //
        make_unique<ReadBallastConfigurationLampAlarmMode>(), //
        make_unique<WriteBallastConfigurationLampAlarmMode>(), //
        make_unique<SubscribeAttributeBallastConfigurationLampAlarmMode>(), //
        make_unique<ReadBallastConfigurationLampBurnHoursTripPoint>(), //
        make_unique<WriteBallastConfigurationLampBurnHoursTripPoint>(), //
        make_unique<SubscribeAttributeBallastConfigurationLampBurnHoursTripPoint>(), //
        make_unique<ReadBallastConfigurationGeneratedCommandList>(), //
        make_unique<SubscribeAttributeBallastConfigurationGeneratedCommandList>(), //
        make_unique<ReadBallastConfigurationAcceptedCommandList>(), //
        make_unique<SubscribeAttributeBallastConfigurationAcceptedCommandList>(), //
        make_unique<ReadBallastConfigurationAttributeList>(), //
        make_unique<SubscribeAttributeBallastConfigurationAttributeList>(), //
        make_unique<ReadBallastConfigurationFeatureMap>(), //
        make_unique<SubscribeAttributeBallastConfigurationFeatureMap>(), //
        make_unique<ReadBallastConfigurationClusterRevision>(), //
        make_unique<SubscribeAttributeBallastConfigurationClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterIlluminanceMeasurement(Commands & commands)
{
    using namespace chip::app::Clusters::IlluminanceMeasurement;

    const char * clusterName = "IlluminanceMeasurement";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadIlluminanceMeasurementMeasuredValue>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeIlluminanceMeasurementMeasuredValue>(), //
        make_unique<ReadIlluminanceMeasurementMinMeasuredValue>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementMinMeasuredValue>(), //
        make_unique<ReadIlluminanceMeasurementMaxMeasuredValue>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementMaxMeasuredValue>(), //
        make_unique<ReadIlluminanceMeasurementTolerance>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementTolerance>(), //
        make_unique<ReadIlluminanceMeasurementLightSensorType>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementLightSensorType>(), //
        make_unique<ReadIlluminanceMeasurementGeneratedCommandList>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementGeneratedCommandList>(), //
        make_unique<ReadIlluminanceMeasurementAcceptedCommandList>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementAcceptedCommandList>(), //
        make_unique<ReadIlluminanceMeasurementAttributeList>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementAttributeList>(), //
        make_unique<ReadIlluminanceMeasurementFeatureMap>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementFeatureMap>(), //
        make_unique<ReadIlluminanceMeasurementClusterRevision>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterTemperatureMeasurement(Commands & commands)
{
    using namespace chip::app::Clusters::TemperatureMeasurement;

    const char * clusterName = "TemperatureMeasurement";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadTemperatureMeasurementMeasuredValue>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeTemperatureMeasurementMeasuredValue>(), //
        make_unique<ReadTemperatureMeasurementMinMeasuredValue>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementMinMeasuredValue>(), //
        make_unique<ReadTemperatureMeasurementMaxMeasuredValue>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementMaxMeasuredValue>(), //
        make_unique<ReadTemperatureMeasurementTolerance>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementTolerance>(), //
        make_unique<ReadTemperatureMeasurementGeneratedCommandList>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementGeneratedCommandList>(), //
        make_unique<ReadTemperatureMeasurementAcceptedCommandList>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementAcceptedCommandList>(), //
        make_unique<ReadTemperatureMeasurementAttributeList>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementAttributeList>(), //
        make_unique<ReadTemperatureMeasurementFeatureMap>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementFeatureMap>(), //
        make_unique<ReadTemperatureMeasurementClusterRevision>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterPressureMeasurement(Commands & commands)
{
    using namespace chip::app::Clusters::PressureMeasurement;

    const char * clusterName = "PressureMeasurement";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadPressureMeasurementMeasuredValue>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributePressureMeasurementMeasuredValue>(), //
        make_unique<ReadPressureMeasurementMinMeasuredValue>(), //
        make_unique<SubscribeAttributePressureMeasurementMinMeasuredValue>(), //
        make_unique<ReadPressureMeasurementMaxMeasuredValue>(), //
        make_unique<SubscribeAttributePressureMeasurementMaxMeasuredValue>(), //
        make_unique<ReadPressureMeasurementTolerance>(), //
        make_unique<SubscribeAttributePressureMeasurementTolerance>(), //
        make_unique<ReadPressureMeasurementScaledValue>(), //
        make_unique<SubscribeAttributePressureMeasurementScaledValue>(), //
        make_unique<ReadPressureMeasurementMinScaledValue>(), //
        make_unique<SubscribeAttributePressureMeasurementMinScaledValue>(), //
        make_unique<ReadPressureMeasurementMaxScaledValue>(), //
        make_unique<SubscribeAttributePressureMeasurementMaxScaledValue>(), //
        make_unique<ReadPressureMeasurementScaledTolerance>(), //
        make_unique<SubscribeAttributePressureMeasurementScaledTolerance>(), //
        make_unique<ReadPressureMeasurementScale>(), //
        make_unique<SubscribeAttributePressureMeasurementScale>(), //
        make_unique<ReadPressureMeasurementGeneratedCommandList>(), //
        make_unique<SubscribeAttributePressureMeasurementGeneratedCommandList>(), //
        make_unique<ReadPressureMeasurementAcceptedCommandList>(), //
        make_unique<SubscribeAttributePressureMeasurementAcceptedCommandList>(), //
        make_unique<ReadPressureMeasurementAttributeList>(), //
        make_unique<SubscribeAttributePressureMeasurementAttributeList>(), //
        make_unique<ReadPressureMeasurementFeatureMap>(), //
        make_unique<SubscribeAttributePressureMeasurementFeatureMap>(), //
        make_unique<ReadPressureMeasurementClusterRevision>(), //
        make_unique<SubscribeAttributePressureMeasurementClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterFlowMeasurement(Commands & commands)
{
    using namespace chip::app::Clusters::FlowMeasurement;

    const char * clusterName = "FlowMeasurement";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadFlowMeasurementMeasuredValue>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeFlowMeasurementMeasuredValue>(), //
        make_unique<ReadFlowMeasurementMinMeasuredValue>(), //
        make_unique<SubscribeAttributeFlowMeasurementMinMeasuredValue>(), //
        make_unique<ReadFlowMeasurementMaxMeasuredValue>(), //
        make_unique<SubscribeAttributeFlowMeasurementMaxMeasuredValue>(), //
        make_unique<ReadFlowMeasurementTolerance>(), //
        make_unique<SubscribeAttributeFlowMeasurementTolerance>(), //
        make_unique<ReadFlowMeasurementGeneratedCommandList>(), //
        make_unique<SubscribeAttributeFlowMeasurementGeneratedCommandList>(), //
        make_unique<ReadFlowMeasurementAcceptedCommandList>(), //
        make_unique<SubscribeAttributeFlowMeasurementAcceptedCommandList>(), //
        make_unique<ReadFlowMeasurementAttributeList>(), //
        make_unique<SubscribeAttributeFlowMeasurementAttributeList>(), //
        make_unique<ReadFlowMeasurementFeatureMap>(), //
        make_unique<SubscribeAttributeFlowMeasurementFeatureMap>(), //
        make_unique<ReadFlowMeasurementClusterRevision>(), //
        make_unique<SubscribeAttributeFlowMeasurementClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterRelativeHumidityMeasurement(Commands & commands)
{
    using namespace chip::app::Clusters::RelativeHumidityMeasurement;

    const char * clusterName = "RelativeHumidityMeasurement";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadRelativeHumidityMeasurementMeasuredValue>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementMeasuredValue>(), //
        make_unique<ReadRelativeHumidityMeasurementMinMeasuredValue>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementMinMeasuredValue>(), //
        make_unique<ReadRelativeHumidityMeasurementMaxMeasuredValue>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementMaxMeasuredValue>(), //
        make_unique<ReadRelativeHumidityMeasurementTolerance>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementTolerance>(), //
        make_unique<ReadRelativeHumidityMeasurementGeneratedCommandList>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementGeneratedCommandList>(), //
        make_unique<ReadRelativeHumidityMeasurementAcceptedCommandList>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementAcceptedCommandList>(), //
        make_unique<ReadRelativeHumidityMeasurementAttributeList>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementAttributeList>(), //
        make_unique<ReadRelativeHumidityMeasurementFeatureMap>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementFeatureMap>(), //
        make_unique<ReadRelativeHumidityMeasurementClusterRevision>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterOccupancySensing(Commands & commands)
{
    using namespace chip::app::Clusters::OccupancySensing;

    const char * clusterName = "OccupancySensing";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadOccupancySensingOccupancy>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeOccupancySensingOccupancy>(), //
        make_unique<ReadOccupancySensingOccupancySensorType>(), //
        make_unique<SubscribeAttributeOccupancySensingOccupancySensorType>(), //
        make_unique<ReadOccupancySensingOccupancySensorTypeBitmap>(), //
        make_unique<SubscribeAttributeOccupancySensingOccupancySensorTypeBitmap>(), //
        make_unique<ReadOccupancySensingPIROccupiedToUnoccupiedDelay>(), //
        make_unique<WriteOccupancySensingPIROccupiedToUnoccupiedDelay>(), //
        make_unique<SubscribeAttributeOccupancySensingPIROccupiedToUnoccupiedDelay>(), //
        make_unique<ReadOccupancySensingPIRUnoccupiedToOccupiedDelay>(), //
        make_unique<WriteOccupancySensingPIRUnoccupiedToOccupiedDelay>(), //
        make_unique<SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedDelay>(), //
        make_unique<ReadOccupancySensingPIRUnoccupiedToOccupiedThreshold>(), //
        make_unique<WriteOccupancySensingPIRUnoccupiedToOccupiedThreshold>(), //
        make_unique<SubscribeAttributeOccupancySensingPIRUnoccupiedToOccupiedThreshold>(), //
        make_unique<ReadOccupancySensingUltrasonicOccupiedToUnoccupiedDelay>(), //
        make_unique<WriteOccupancySensingUltrasonicOccupiedToUnoccupiedDelay>(), //
        make_unique<SubscribeAttributeOccupancySensingUltrasonicOccupiedToUnoccupiedDelay>(), //
        make_unique<ReadOccupancySensingUltrasonicUnoccupiedToOccupiedDelay>(), //
        make_unique<WriteOccupancySensingUltrasonicUnoccupiedToOccupiedDelay>(), //
        make_unique<SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedDelay>(), //
        make_unique<ReadOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold>(), //
        make_unique<WriteOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold>(), //
        make_unique<SubscribeAttributeOccupancySensingUltrasonicUnoccupiedToOccupiedThreshold>(), //
        make_unique<ReadOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay>(), //
        make_unique<WriteOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay>(), //
        make_unique<SubscribeAttributeOccupancySensingPhysicalContactOccupiedToUnoccupiedDelay>(), //
        make_unique<ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay>(), //
        make_unique<WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay>(), //
        make_unique<SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedDelay>(), //
        make_unique<ReadOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold>(), //
        make_unique<WriteOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold>(), //
        make_unique<SubscribeAttributeOccupancySensingPhysicalContactUnoccupiedToOccupiedThreshold>(), //
        make_unique<ReadOccupancySensingGeneratedCommandList>(), //
        make_unique<SubscribeAttributeOccupancySensingGeneratedCommandList>(), //
        make_unique<ReadOccupancySensingAcceptedCommandList>(), //
        make_unique<SubscribeAttributeOccupancySensingAcceptedCommandList>(), //
        make_unique<ReadOccupancySensingAttributeList>(), //
        make_unique<SubscribeAttributeOccupancySensingAttributeList>(), //
        make_unique<ReadOccupancySensingFeatureMap>(), //
        make_unique<SubscribeAttributeOccupancySensingFeatureMap>(), //
        make_unique<ReadOccupancySensingClusterRevision>(), //
        make_unique<SubscribeAttributeOccupancySensingClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterWakeOnLan(Commands & commands)
{
    using namespace chip::app::Clusters::WakeOnLan;

    const char * clusterName = "WakeOnLan";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadWakeOnLanMACAddress>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeWakeOnLanMACAddress>(), //
        make_unique<ReadWakeOnLanGeneratedCommandList>(), //
        make_unique<SubscribeAttributeWakeOnLanGeneratedCommandList>(), //
        make_unique<ReadWakeOnLanAcceptedCommandList>(), //
        make_unique<SubscribeAttributeWakeOnLanAcceptedCommandList>(), //
        make_unique<ReadWakeOnLanAttributeList>(), //
        make_unique<SubscribeAttributeWakeOnLanAttributeList>(), //
        make_unique<ReadWakeOnLanFeatureMap>(), //
        make_unique<SubscribeAttributeWakeOnLanFeatureMap>(), //
        make_unique<ReadWakeOnLanClusterRevision>(), //
        make_unique<SubscribeAttributeWakeOnLanClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterChannel(Commands & commands)
{
    using namespace chip::app::Clusters::Channel;

    const char * clusterName = "Channel";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ChannelChangeChannel>(), //
        make_unique<ChannelChangeChannelByNumber>(), //
        make_unique<ChannelSkipChannel>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadChannelChannelList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeChannelChannelList>(), //
        make_unique<ReadChannelLineup>(), //
        make_unique<SubscribeAttributeChannelLineup>(), //
        make_unique<ReadChannelCurrentChannel>(), //
        make_unique<SubscribeAttributeChannelCurrentChannel>(), //
        make_unique<ReadChannelGeneratedCommandList>(), //
        make_unique<SubscribeAttributeChannelGeneratedCommandList>(), //
        make_unique<ReadChannelAcceptedCommandList>(), //
        make_unique<SubscribeAttributeChannelAcceptedCommandList>(), //
        make_unique<ReadChannelAttributeList>(), //
        make_unique<SubscribeAttributeChannelAttributeList>(), //
        make_unique<ReadChannelFeatureMap>(), //
        make_unique<SubscribeAttributeChannelFeatureMap>(), //
        make_unique<ReadChannelClusterRevision>(), //
        make_unique<SubscribeAttributeChannelClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterTargetNavigator(Commands & commands)
{
    using namespace chip::app::Clusters::TargetNavigator;

    const char * clusterName = "TargetNavigator";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<TargetNavigatorNavigateTarget>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadTargetNavigatorTargetList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeTargetNavigatorTargetList>(), //
        make_unique<ReadTargetNavigatorCurrentTarget>(), //
        make_unique<SubscribeAttributeTargetNavigatorCurrentTarget>(), //
        make_unique<ReadTargetNavigatorGeneratedCommandList>(), //
        make_unique<SubscribeAttributeTargetNavigatorGeneratedCommandList>(), //
        make_unique<ReadTargetNavigatorAcceptedCommandList>(), //
        make_unique<SubscribeAttributeTargetNavigatorAcceptedCommandList>(), //
        make_unique<ReadTargetNavigatorAttributeList>(), //
        make_unique<SubscribeAttributeTargetNavigatorAttributeList>(), //
        make_unique<ReadTargetNavigatorFeatureMap>(), //
        make_unique<SubscribeAttributeTargetNavigatorFeatureMap>(), //
        make_unique<ReadTargetNavigatorClusterRevision>(), //
        make_unique<SubscribeAttributeTargetNavigatorClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterMediaPlayback(Commands & commands)
{
    using namespace chip::app::Clusters::MediaPlayback;

    const char * clusterName = "MediaPlayback";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<MediaPlaybackPlay>(), //
        make_unique<MediaPlaybackPause>(), //
        make_unique<MediaPlaybackStop>(), //
        make_unique<MediaPlaybackStartOver>(), //
        make_unique<MediaPlaybackPrevious>(), //
        make_unique<MediaPlaybackNext>(), //
        make_unique<MediaPlaybackRewind>(), //
        make_unique<MediaPlaybackFastForward>(), //
        make_unique<MediaPlaybackSkipForward>(), //
        make_unique<MediaPlaybackSkipBackward>(), //
        make_unique<MediaPlaybackSeek>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadMediaPlaybackCurrentState>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeMediaPlaybackCurrentState>(), //
        make_unique<ReadMediaPlaybackStartTime>(), //
        make_unique<SubscribeAttributeMediaPlaybackStartTime>(), //
        make_unique<ReadMediaPlaybackDuration>(), //
        make_unique<SubscribeAttributeMediaPlaybackDuration>(), //
        make_unique<ReadMediaPlaybackSampledPosition>(), //
        make_unique<SubscribeAttributeMediaPlaybackSampledPosition>(), //
        make_unique<ReadMediaPlaybackPlaybackSpeed>(), //
        make_unique<SubscribeAttributeMediaPlaybackPlaybackSpeed>(), //
        make_unique<ReadMediaPlaybackSeekRangeEnd>(), //
        make_unique<SubscribeAttributeMediaPlaybackSeekRangeEnd>(), //
        make_unique<ReadMediaPlaybackSeekRangeStart>(), //
        make_unique<SubscribeAttributeMediaPlaybackSeekRangeStart>(), //
        make_unique<ReadMediaPlaybackGeneratedCommandList>(), //
        make_unique<SubscribeAttributeMediaPlaybackGeneratedCommandList>(), //
        make_unique<ReadMediaPlaybackAcceptedCommandList>(), //
        make_unique<SubscribeAttributeMediaPlaybackAcceptedCommandList>(), //
        make_unique<ReadMediaPlaybackAttributeList>(), //
        make_unique<SubscribeAttributeMediaPlaybackAttributeList>(), //
        make_unique<ReadMediaPlaybackFeatureMap>(), //
        make_unique<SubscribeAttributeMediaPlaybackFeatureMap>(), //
        make_unique<ReadMediaPlaybackClusterRevision>(), //
        make_unique<SubscribeAttributeMediaPlaybackClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterMediaInput(Commands & commands)
{
    using namespace chip::app::Clusters::MediaInput;

    const char * clusterName = "MediaInput";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<MediaInputSelectInput>(), //
        make_unique<MediaInputShowInputStatus>(), //
        make_unique<MediaInputHideInputStatus>(), //
        make_unique<MediaInputRenameInput>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadMediaInputInputList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeMediaInputInputList>(), //
        make_unique<ReadMediaInputCurrentInput>(), //
        make_unique<SubscribeAttributeMediaInputCurrentInput>(), //
        make_unique<ReadMediaInputGeneratedCommandList>(), //
        make_unique<SubscribeAttributeMediaInputGeneratedCommandList>(), //
        make_unique<ReadMediaInputAcceptedCommandList>(), //
        make_unique<SubscribeAttributeMediaInputAcceptedCommandList>(), //
        make_unique<ReadMediaInputAttributeList>(), //
        make_unique<SubscribeAttributeMediaInputAttributeList>(), //
        make_unique<ReadMediaInputFeatureMap>(), //
        make_unique<SubscribeAttributeMediaInputFeatureMap>(), //
        make_unique<ReadMediaInputClusterRevision>(), //
        make_unique<SubscribeAttributeMediaInputClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterLowPower(Commands & commands)
{
    using namespace chip::app::Clusters::LowPower;

    const char * clusterName = "LowPower";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<LowPowerSleep>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadLowPowerGeneratedCommandList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeLowPowerGeneratedCommandList>(), //
        make_unique<ReadLowPowerAcceptedCommandList>(), //
        make_unique<SubscribeAttributeLowPowerAcceptedCommandList>(), //
        make_unique<ReadLowPowerAttributeList>(), //
        make_unique<SubscribeAttributeLowPowerAttributeList>(), //
        make_unique<ReadLowPowerFeatureMap>(), //
        make_unique<SubscribeAttributeLowPowerFeatureMap>(), //
        make_unique<ReadLowPowerClusterRevision>(), //
        make_unique<SubscribeAttributeLowPowerClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterKeypadInput(Commands & commands)
{
    using namespace chip::app::Clusters::KeypadInput;

    const char * clusterName = "KeypadInput";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<KeypadInputSendKey>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadKeypadInputGeneratedCommandList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeKeypadInputGeneratedCommandList>(), //
        make_unique<ReadKeypadInputAcceptedCommandList>(), //
        make_unique<SubscribeAttributeKeypadInputAcceptedCommandList>(), //
        make_unique<ReadKeypadInputAttributeList>(), //
        make_unique<SubscribeAttributeKeypadInputAttributeList>(), //
        make_unique<ReadKeypadInputFeatureMap>(), //
        make_unique<SubscribeAttributeKeypadInputFeatureMap>(), //
        make_unique<ReadKeypadInputClusterRevision>(), //
        make_unique<SubscribeAttributeKeypadInputClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterContentLauncher(Commands & commands)
{
    using namespace chip::app::Clusters::ContentLauncher;

    const char * clusterName = "ContentLauncher";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ContentLauncherLaunchContent>(), //
        make_unique<ContentLauncherLaunchURL>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadContentLauncherAcceptHeader>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeContentLauncherAcceptHeader>(), //
        make_unique<ReadContentLauncherSupportedStreamingProtocols>(), //
        make_unique<WriteContentLauncherSupportedStreamingProtocols>(), //
        make_unique<SubscribeAttributeContentLauncherSupportedStreamingProtocols>(), //
        make_unique<ReadContentLauncherGeneratedCommandList>(), //
        make_unique<SubscribeAttributeContentLauncherGeneratedCommandList>(), //
        make_unique<ReadContentLauncherAcceptedCommandList>(), //
        make_unique<SubscribeAttributeContentLauncherAcceptedCommandList>(), //
        make_unique<ReadContentLauncherAttributeList>(), //
        make_unique<SubscribeAttributeContentLauncherAttributeList>(), //
        make_unique<ReadContentLauncherFeatureMap>(), //
        make_unique<SubscribeAttributeContentLauncherFeatureMap>(), //
        make_unique<ReadContentLauncherClusterRevision>(), //
        make_unique<SubscribeAttributeContentLauncherClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterAudioOutput(Commands & commands)
{
    using namespace chip::app::Clusters::AudioOutput;

    const char * clusterName = "AudioOutput";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<AudioOutputSelectOutput>(), //
        make_unique<AudioOutputRenameOutput>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadAudioOutputOutputList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeAudioOutputOutputList>(), //
        make_unique<ReadAudioOutputCurrentOutput>(), //
        make_unique<SubscribeAttributeAudioOutputCurrentOutput>(), //
        make_unique<ReadAudioOutputGeneratedCommandList>(), //
        make_unique<SubscribeAttributeAudioOutputGeneratedCommandList>(), //
        make_unique<ReadAudioOutputAcceptedCommandList>(), //
        make_unique<SubscribeAttributeAudioOutputAcceptedCommandList>(), //
        make_unique<ReadAudioOutputAttributeList>(), //
        make_unique<SubscribeAttributeAudioOutputAttributeList>(), //
        make_unique<ReadAudioOutputFeatureMap>(), //
        make_unique<SubscribeAttributeAudioOutputFeatureMap>(), //
        make_unique<ReadAudioOutputClusterRevision>(), //
        make_unique<SubscribeAttributeAudioOutputClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterApplicationLauncher(Commands & commands)
{
    using namespace chip::app::Clusters::ApplicationLauncher;

    const char * clusterName = "ApplicationLauncher";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ApplicationLauncherLaunchApp>(), //
        make_unique<ApplicationLauncherStopApp>(), //
        make_unique<ApplicationLauncherHideApp>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadApplicationLauncherCatalogList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeApplicationLauncherCatalogList>(), //
        make_unique<ReadApplicationLauncherCurrentApp>(), //
        make_unique<WriteApplicationLauncherCurrentApp>(), //
        make_unique<SubscribeAttributeApplicationLauncherCurrentApp>(), //
        make_unique<ReadApplicationLauncherGeneratedCommandList>(), //
        make_unique<SubscribeAttributeApplicationLauncherGeneratedCommandList>(), //
        make_unique<ReadApplicationLauncherAcceptedCommandList>(), //
        make_unique<SubscribeAttributeApplicationLauncherAcceptedCommandList>(), //
        make_unique<ReadApplicationLauncherAttributeList>(), //
        make_unique<SubscribeAttributeApplicationLauncherAttributeList>(), //
        make_unique<ReadApplicationLauncherFeatureMap>(), //
        make_unique<SubscribeAttributeApplicationLauncherFeatureMap>(), //
        make_unique<ReadApplicationLauncherClusterRevision>(), //
        make_unique<SubscribeAttributeApplicationLauncherClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterApplicationBasic(Commands & commands)
{
    using namespace chip::app::Clusters::ApplicationBasic;

    const char * clusterName = "ApplicationBasic";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadApplicationBasicVendorName>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeApplicationBasicVendorName>(), //
        make_unique<ReadApplicationBasicVendorID>(), //
        make_unique<SubscribeAttributeApplicationBasicVendorID>(), //
        make_unique<ReadApplicationBasicApplicationName>(), //
        make_unique<SubscribeAttributeApplicationBasicApplicationName>(), //
        make_unique<ReadApplicationBasicProductID>(), //
        make_unique<SubscribeAttributeApplicationBasicProductID>(), //
        make_unique<ReadApplicationBasicApplication>(), //
        make_unique<SubscribeAttributeApplicationBasicApplication>(), //
        make_unique<ReadApplicationBasicStatus>(), //
        make_unique<SubscribeAttributeApplicationBasicStatus>(), //
        make_unique<ReadApplicationBasicApplicationVersion>(), //
        make_unique<SubscribeAttributeApplicationBasicApplicationVersion>(), //
        make_unique<ReadApplicationBasicAllowedVendorList>(), //
        make_unique<SubscribeAttributeApplicationBasicAllowedVendorList>(), //
        make_unique<ReadApplicationBasicGeneratedCommandList>(), //
        make_unique<SubscribeAttributeApplicationBasicGeneratedCommandList>(), //
        make_unique<ReadApplicationBasicAcceptedCommandList>(), //
        make_unique<SubscribeAttributeApplicationBasicAcceptedCommandList>(), //
        make_unique<ReadApplicationBasicAttributeList>(), //
        make_unique<SubscribeAttributeApplicationBasicAttributeList>(), //
        make_unique<ReadApplicationBasicFeatureMap>(), //
        make_unique<SubscribeAttributeApplicationBasicFeatureMap>(), //
        make_unique<ReadApplicationBasicClusterRevision>(), //
        make_unique<SubscribeAttributeApplicationBasicClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterAccountLogin(Commands & commands)
{
    using namespace chip::app::Clusters::AccountLogin;

    const char * clusterName = "AccountLogin";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<AccountLoginGetSetupPIN>(), //
        make_unique<AccountLoginLogin>(), //
        make_unique<AccountLoginLogout>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadAccountLoginGeneratedCommandList>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeAccountLoginGeneratedCommandList>(), //
        make_unique<ReadAccountLoginAcceptedCommandList>(), //
        make_unique<SubscribeAttributeAccountLoginAcceptedCommandList>(), //
        make_unique<ReadAccountLoginAttributeList>(), //
        make_unique<SubscribeAttributeAccountLoginAttributeList>(), //
        make_unique<ReadAccountLoginFeatureMap>(), //
        make_unique<SubscribeAttributeAccountLoginFeatureMap>(), //
        make_unique<ReadAccountLoginClusterRevision>(), //
        make_unique<SubscribeAttributeAccountLoginClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterElectricalMeasurement(Commands & commands)
{
    using namespace chip::app::Clusters::ElectricalMeasurement;

    const char * clusterName = "ElectricalMeasurement";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ElectricalMeasurementGetProfileInfoCommand>(), //
        make_unique<ElectricalMeasurementGetMeasurementProfileCommand>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadElectricalMeasurementMeasurementType>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasurementType>(), //
        make_unique<ReadElectricalMeasurementDcVoltage>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcVoltage>(), //
        make_unique<ReadElectricalMeasurementDcVoltageMin>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcVoltageMin>(), //
        make_unique<ReadElectricalMeasurementDcVoltageMax>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcVoltageMax>(), //
        make_unique<ReadElectricalMeasurementDcCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcCurrent>(), //
        make_unique<ReadElectricalMeasurementDcCurrentMin>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcCurrentMin>(), //
        make_unique<ReadElectricalMeasurementDcCurrentMax>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcCurrentMax>(), //
        make_unique<ReadElectricalMeasurementDcPower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcPower>(), //
        make_unique<ReadElectricalMeasurementDcPowerMin>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcPowerMin>(), //
        make_unique<ReadElectricalMeasurementDcPowerMax>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcPowerMax>(), //
        make_unique<ReadElectricalMeasurementDcVoltageMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcVoltageMultiplier>(), //
        make_unique<ReadElectricalMeasurementDcVoltageDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcVoltageDivisor>(), //
        make_unique<ReadElectricalMeasurementDcCurrentMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcCurrentMultiplier>(), //
        make_unique<ReadElectricalMeasurementDcCurrentDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcCurrentDivisor>(), //
        make_unique<ReadElectricalMeasurementDcPowerMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcPowerMultiplier>(), //
        make_unique<ReadElectricalMeasurementDcPowerDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementDcPowerDivisor>(), //
        make_unique<ReadElectricalMeasurementAcFrequency>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcFrequency>(), //
        make_unique<ReadElectricalMeasurementAcFrequencyMin>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcFrequencyMin>(), //
        make_unique<ReadElectricalMeasurementAcFrequencyMax>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcFrequencyMax>(), //
        make_unique<ReadElectricalMeasurementNeutralCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementNeutralCurrent>(), //
        make_unique<ReadElectricalMeasurementTotalActivePower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementTotalActivePower>(), //
        make_unique<ReadElectricalMeasurementTotalReactivePower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementTotalReactivePower>(), //
        make_unique<ReadElectricalMeasurementTotalApparentPower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementTotalApparentPower>(), //
        make_unique<ReadElectricalMeasurementMeasured1stHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasured1stHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasured3rdHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasured3rdHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasured5thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasured5thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasured7thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasured7thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasured9thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasured9thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasured11thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasured11thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasuredPhase1stHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasuredPhase1stHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasuredPhase3rdHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasuredPhase3rdHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasuredPhase5thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasuredPhase5thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasuredPhase7thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasuredPhase7thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasuredPhase9thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasuredPhase9thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementMeasuredPhase11thHarmonicCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementMeasuredPhase11thHarmonicCurrent>(), //
        make_unique<ReadElectricalMeasurementAcFrequencyMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcFrequencyMultiplier>(), //
        make_unique<ReadElectricalMeasurementAcFrequencyDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcFrequencyDivisor>(), //
        make_unique<ReadElectricalMeasurementPowerMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementPowerMultiplier>(), //
        make_unique<ReadElectricalMeasurementPowerDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementPowerDivisor>(), //
        make_unique<ReadElectricalMeasurementHarmonicCurrentMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementHarmonicCurrentMultiplier>(), //
        make_unique<ReadElectricalMeasurementPhaseHarmonicCurrentMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementPhaseHarmonicCurrentMultiplier>(), //
        make_unique<ReadElectricalMeasurementInstantaneousVoltage>(), //
        make_unique<SubscribeAttributeElectricalMeasurementInstantaneousVoltage>(), //
        make_unique<ReadElectricalMeasurementInstantaneousLineCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementInstantaneousLineCurrent>(), //
        make_unique<ReadElectricalMeasurementInstantaneousActiveCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementInstantaneousActiveCurrent>(), //
        make_unique<ReadElectricalMeasurementInstantaneousReactiveCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementInstantaneousReactiveCurrent>(), //
        make_unique<ReadElectricalMeasurementInstantaneousPower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementInstantaneousPower>(), //
        make_unique<ReadElectricalMeasurementRmsVoltage>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltage>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageMin>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageMin>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageMax>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageMax>(), //
        make_unique<ReadElectricalMeasurementRmsCurrent>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrent>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentMin>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentMin>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentMax>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentMax>(), //
        make_unique<ReadElectricalMeasurementActivePower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePower>(), //
        make_unique<ReadElectricalMeasurementActivePowerMin>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerMin>(), //
        make_unique<ReadElectricalMeasurementActivePowerMax>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerMax>(), //
        make_unique<ReadElectricalMeasurementReactivePower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementReactivePower>(), //
        make_unique<ReadElectricalMeasurementApparentPower>(), //
        make_unique<SubscribeAttributeElectricalMeasurementApparentPower>(), //
        make_unique<ReadElectricalMeasurementPowerFactor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementPowerFactor>(), //
        make_unique<ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriod>(), //
        make_unique<WriteElectricalMeasurementAverageRmsVoltageMeasurementPeriod>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriod>(), //
        make_unique<ReadElectricalMeasurementAverageRmsUnderVoltageCounter>(), //
        make_unique<WriteElectricalMeasurementAverageRmsUnderVoltageCounter>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounter>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeOverVoltagePeriod>(), //
        make_unique<WriteElectricalMeasurementRmsExtremeOverVoltagePeriod>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriod>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeUnderVoltagePeriod>(), //
        make_unique<WriteElectricalMeasurementRmsExtremeUnderVoltagePeriod>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriod>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSagPeriod>(), //
        make_unique<WriteElectricalMeasurementRmsVoltageSagPeriod>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriod>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSwellPeriod>(), //
        make_unique<WriteElectricalMeasurementRmsVoltageSwellPeriod>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriod>(), //
        make_unique<ReadElectricalMeasurementAcVoltageMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcVoltageMultiplier>(), //
        make_unique<ReadElectricalMeasurementAcVoltageDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcVoltageDivisor>(), //
        make_unique<ReadElectricalMeasurementAcCurrentMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcCurrentMultiplier>(), //
        make_unique<ReadElectricalMeasurementAcCurrentDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcCurrentDivisor>(), //
        make_unique<ReadElectricalMeasurementAcPowerMultiplier>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcPowerMultiplier>(), //
        make_unique<ReadElectricalMeasurementAcPowerDivisor>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcPowerDivisor>(), //
        make_unique<ReadElectricalMeasurementOverloadAlarmsMask>(), //
        make_unique<WriteElectricalMeasurementOverloadAlarmsMask>(), //
        make_unique<SubscribeAttributeElectricalMeasurementOverloadAlarmsMask>(), //
        make_unique<ReadElectricalMeasurementVoltageOverload>(), //
        make_unique<SubscribeAttributeElectricalMeasurementVoltageOverload>(), //
        make_unique<ReadElectricalMeasurementCurrentOverload>(), //
        make_unique<SubscribeAttributeElectricalMeasurementCurrentOverload>(), //
        make_unique<ReadElectricalMeasurementAcOverloadAlarmsMask>(), //
        make_unique<WriteElectricalMeasurementAcOverloadAlarmsMask>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcOverloadAlarmsMask>(), //
        make_unique<ReadElectricalMeasurementAcVoltageOverload>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcVoltageOverload>(), //
        make_unique<ReadElectricalMeasurementAcCurrentOverload>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcCurrentOverload>(), //
        make_unique<ReadElectricalMeasurementAcActivePowerOverload>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcActivePowerOverload>(), //
        make_unique<ReadElectricalMeasurementAcReactivePowerOverload>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcReactivePowerOverload>(), //
        make_unique<ReadElectricalMeasurementAverageRmsOverVoltage>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsOverVoltage>(), //
        make_unique<ReadElectricalMeasurementAverageRmsUnderVoltage>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltage>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeOverVoltage>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltage>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeUnderVoltage>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltage>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSag>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSag>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSwell>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSwell>(), //
        make_unique<ReadElectricalMeasurementLineCurrentPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementLineCurrentPhaseB>(), //
        make_unique<ReadElectricalMeasurementActiveCurrentPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActiveCurrentPhaseB>(), //
        make_unique<ReadElectricalMeasurementReactiveCurrentPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsVoltagePhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltagePhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageMinPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageMaxPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentMinPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentMaxPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseB>(), //
        make_unique<ReadElectricalMeasurementActivePowerPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerPhaseB>(), //
        make_unique<ReadElectricalMeasurementActivePowerMinPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerMinPhaseB>(), //
        make_unique<ReadElectricalMeasurementActivePowerMaxPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseB>(), //
        make_unique<ReadElectricalMeasurementReactivePowerPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementReactivePowerPhaseB>(), //
        make_unique<ReadElectricalMeasurementApparentPowerPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementApparentPowerPhaseB>(), //
        make_unique<ReadElectricalMeasurementPowerFactorPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementPowerFactorPhaseB>(), //
        make_unique<ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseB>(), //
        make_unique<ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseB>(), //
        make_unique<ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSagPeriodPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseB>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseB>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseB>(), //
        make_unique<ReadElectricalMeasurementLineCurrentPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementLineCurrentPhaseC>(), //
        make_unique<ReadElectricalMeasurementActiveCurrentPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActiveCurrentPhaseC>(), //
        make_unique<ReadElectricalMeasurementReactiveCurrentPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementReactiveCurrentPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsVoltagePhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltagePhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageMinPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageMinPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageMaxPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageMaxPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentMinPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentMinPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsCurrentMaxPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsCurrentMaxPhaseC>(), //
        make_unique<ReadElectricalMeasurementActivePowerPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerPhaseC>(), //
        make_unique<ReadElectricalMeasurementActivePowerMinPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerMinPhaseC>(), //
        make_unique<ReadElectricalMeasurementActivePowerMaxPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementActivePowerMaxPhaseC>(), //
        make_unique<ReadElectricalMeasurementReactivePowerPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementReactivePowerPhaseC>(), //
        make_unique<ReadElectricalMeasurementApparentPowerPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementApparentPowerPhaseC>(), //
        make_unique<ReadElectricalMeasurementPowerFactorPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementPowerFactorPhaseC>(), //
        make_unique<ReadElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsVoltageMeasurementPeriodPhaseC>(), //
        make_unique<ReadElectricalMeasurementAverageRmsOverVoltageCounterPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsOverVoltageCounterPhaseC>(), //
        make_unique<ReadElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAverageRmsUnderVoltageCounterPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeOverVoltagePeriodPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsExtremeUnderVoltagePeriodPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSagPeriodPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSagPeriodPhaseC>(), //
        make_unique<ReadElectricalMeasurementRmsVoltageSwellPeriodPhaseC>(), //
        make_unique<SubscribeAttributeElectricalMeasurementRmsVoltageSwellPeriodPhaseC>(), //
        make_unique<ReadElectricalMeasurementGeneratedCommandList>(), //
        make_unique<SubscribeAttributeElectricalMeasurementGeneratedCommandList>(), //
        make_unique<ReadElectricalMeasurementAcceptedCommandList>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAcceptedCommandList>(), //
        make_unique<ReadElectricalMeasurementAttributeList>(), //
        make_unique<SubscribeAttributeElectricalMeasurementAttributeList>(), //
        make_unique<ReadElectricalMeasurementFeatureMap>(), //
        make_unique<SubscribeAttributeElectricalMeasurementFeatureMap>(), //
        make_unique<ReadElectricalMeasurementClusterRevision>(), //
        make_unique<SubscribeAttributeElectricalMeasurementClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterUnitTesting(Commands & commands)
{
    using namespace chip::app::Clusters::UnitTesting;

    const char * clusterName = "UnitTesting";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<UnitTestingTest>(), //
        make_unique<UnitTestingTestNotHandled>(), //
        make_unique<UnitTestingTestSpecific>(), //
        make_unique<UnitTestingTestUnknownCommand>(), //
        make_unique<UnitTestingTestAddArguments>(), //
        make_unique<UnitTestingTestSimpleArgumentRequest>(), //
        make_unique<UnitTestingTestStructArrayArgumentRequest>(), //
        make_unique<UnitTestingTestStructArgumentRequest>(), //
        make_unique<UnitTestingTestNestedStructArgumentRequest>(), //
        make_unique<UnitTestingTestListStructArgumentRequest>(), //
        make_unique<UnitTestingTestListInt8UArgumentRequest>(), //
        make_unique<UnitTestingTestNestedStructListArgumentRequest>(), //
        make_unique<UnitTestingTestListNestedStructListArgumentRequest>(), //
        make_unique<UnitTestingTestListInt8UReverseRequest>(), //
        make_unique<UnitTestingTestEnumsRequest>(), //
        make_unique<UnitTestingTestNullableOptionalRequest>(), //
        make_unique<UnitTestingTestComplexNullableOptionalRequest>(), //
        make_unique<UnitTestingSimpleStructEchoRequest>(), //
        make_unique<UnitTestingTimedInvokeRequest>(), //
        make_unique<UnitTestingTestSimpleOptionalArgumentRequest>(), //
        make_unique<UnitTestingTestEmitTestEventRequest>(), //
        make_unique<UnitTestingTestEmitTestFabricScopedEventRequest>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadUnitTestingBoolean>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<WriteUnitTestingBoolean>(), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeUnitTestingBoolean>(), //
        make_unique<ReadUnitTestingBitmap8>(), //
        make_unique<WriteUnitTestingBitmap8>(), //
        make_unique<SubscribeAttributeUnitTestingBitmap8>(), //
        make_unique<ReadUnitTestingBitmap16>(), //
        make_unique<WriteUnitTestingBitmap16>(), //
        make_unique<SubscribeAttributeUnitTestingBitmap16>(), //
        make_unique<ReadUnitTestingBitmap32>(), //
        make_unique<WriteUnitTestingBitmap32>(), //
        make_unique<SubscribeAttributeUnitTestingBitmap32>(), //
        make_unique<ReadUnitTestingBitmap64>(), //
        make_unique<WriteUnitTestingBitmap64>(), //
        make_unique<SubscribeAttributeUnitTestingBitmap64>(), //
        make_unique<ReadUnitTestingInt8u>(), //
        make_unique<WriteUnitTestingInt8u>(), //
        make_unique<SubscribeAttributeUnitTestingInt8u>(), //
        make_unique<ReadUnitTestingInt16u>(), //
        make_unique<WriteUnitTestingInt16u>(), //
        make_unique<SubscribeAttributeUnitTestingInt16u>(), //
        make_unique<ReadUnitTestingInt24u>(), //
        make_unique<WriteUnitTestingInt24u>(), //
        make_unique<SubscribeAttributeUnitTestingInt24u>(), //
        make_unique<ReadUnitTestingInt32u>(), //
        make_unique<WriteUnitTestingInt32u>(), //
        make_unique<SubscribeAttributeUnitTestingInt32u>(), //
        make_unique<ReadUnitTestingInt40u>(), //
        make_unique<WriteUnitTestingInt40u>(), //
        make_unique<SubscribeAttributeUnitTestingInt40u>(), //
        make_unique<ReadUnitTestingInt48u>(), //
        make_unique<WriteUnitTestingInt48u>(), //
        make_unique<SubscribeAttributeUnitTestingInt48u>(), //
        make_unique<ReadUnitTestingInt56u>(), //
        make_unique<WriteUnitTestingInt56u>(), //
        make_unique<SubscribeAttributeUnitTestingInt56u>(), //
        make_unique<ReadUnitTestingInt64u>(), //
        make_unique<WriteUnitTestingInt64u>(), //
        make_unique<SubscribeAttributeUnitTestingInt64u>(), //
        make_unique<ReadUnitTestingInt8s>(), //
        make_unique<WriteUnitTestingInt8s>(), //
        make_unique<SubscribeAttributeUnitTestingInt8s>(), //
        make_unique<ReadUnitTestingInt16s>(), //
        make_unique<WriteUnitTestingInt16s>(), //
        make_unique<SubscribeAttributeUnitTestingInt16s>(), //
        make_unique<ReadUnitTestingInt24s>(), //
        make_unique<WriteUnitTestingInt24s>(), //
        make_unique<SubscribeAttributeUnitTestingInt24s>(), //
        make_unique<ReadUnitTestingInt32s>(), //
        make_unique<WriteUnitTestingInt32s>(), //
        make_unique<SubscribeAttributeUnitTestingInt32s>(), //
        make_unique<ReadUnitTestingInt40s>(), //
        make_unique<WriteUnitTestingInt40s>(), //
        make_unique<SubscribeAttributeUnitTestingInt40s>(), //
        make_unique<ReadUnitTestingInt48s>(), //
        make_unique<WriteUnitTestingInt48s>(), //
        make_unique<SubscribeAttributeUnitTestingInt48s>(), //
        make_unique<ReadUnitTestingInt56s>(), //
        make_unique<WriteUnitTestingInt56s>(), //
        make_unique<SubscribeAttributeUnitTestingInt56s>(), //
        make_unique<ReadUnitTestingInt64s>(), //
        make_unique<WriteUnitTestingInt64s>(), //
        make_unique<SubscribeAttributeUnitTestingInt64s>(), //
        make_unique<ReadUnitTestingEnum8>(), //
        make_unique<WriteUnitTestingEnum8>(), //
        make_unique<SubscribeAttributeUnitTestingEnum8>(), //
        make_unique<ReadUnitTestingEnum16>(), //
        make_unique<WriteUnitTestingEnum16>(), //
        make_unique<SubscribeAttributeUnitTestingEnum16>(), //
        make_unique<ReadUnitTestingFloatSingle>(), //
        make_unique<WriteUnitTestingFloatSingle>(), //
        make_unique<SubscribeAttributeUnitTestingFloatSingle>(), //
        make_unique<ReadUnitTestingFloatDouble>(), //
        make_unique<WriteUnitTestingFloatDouble>(), //
        make_unique<SubscribeAttributeUnitTestingFloatDouble>(), //
        make_unique<ReadUnitTestingOctetString>(), //
        make_unique<WriteUnitTestingOctetString>(), //
        make_unique<SubscribeAttributeUnitTestingOctetString>(), //
        make_unique<ReadUnitTestingListInt8u>(), //
        make_unique<WriteUnitTestingListInt8u>(), //
        make_unique<SubscribeAttributeUnitTestingListInt8u>(), //
        make_unique<ReadUnitTestingListOctetString>(), //
        make_unique<WriteUnitTestingListOctetString>(), //
        make_unique<SubscribeAttributeUnitTestingListOctetString>(), //
        make_unique<ReadUnitTestingListStructOctetString>(), //
        make_unique<WriteUnitTestingListStructOctetString>(), //
        make_unique<SubscribeAttributeUnitTestingListStructOctetString>(), //
        make_unique<ReadUnitTestingLongOctetString>(), //
        make_unique<WriteUnitTestingLongOctetString>(), //
        make_unique<SubscribeAttributeUnitTestingLongOctetString>(), //
        make_unique<ReadUnitTestingCharString>(), //
        make_unique<WriteUnitTestingCharString>(), //
        make_unique<SubscribeAttributeUnitTestingCharString>(), //
        make_unique<ReadUnitTestingLongCharString>(), //
        make_unique<WriteUnitTestingLongCharString>(), //
        make_unique<SubscribeAttributeUnitTestingLongCharString>(), //
        make_unique<ReadUnitTestingEpochUs>(), //
        make_unique<WriteUnitTestingEpochUs>(), //
        make_unique<SubscribeAttributeUnitTestingEpochUs>(), //
        make_unique<ReadUnitTestingEpochS>(), //
        make_unique<WriteUnitTestingEpochS>(), //
        make_unique<SubscribeAttributeUnitTestingEpochS>(), //
        make_unique<ReadUnitTestingVendorId>(), //
        make_unique<WriteUnitTestingVendorId>(), //
        make_unique<SubscribeAttributeUnitTestingVendorId>(), //
        make_unique<ReadUnitTestingListNullablesAndOptionalsStruct>(), //
        make_unique<WriteUnitTestingListNullablesAndOptionalsStruct>(), //
        make_unique<SubscribeAttributeUnitTestingListNullablesAndOptionalsStruct>(), //
        make_unique<ReadUnitTestingEnumAttr>(), //
        make_unique<WriteUnitTestingEnumAttr>(), //
        make_unique<SubscribeAttributeUnitTestingEnumAttr>(), //
        make_unique<ReadUnitTestingStructAttr>(), //
        make_unique<WriteUnitTestingStructAttr>(), //
        make_unique<SubscribeAttributeUnitTestingStructAttr>(), //
        make_unique<ReadUnitTestingRangeRestrictedInt8u>(), //
        make_unique<WriteUnitTestingRangeRestrictedInt8u>(), //
        make_unique<SubscribeAttributeUnitTestingRangeRestrictedInt8u>(), //
        make_unique<ReadUnitTestingRangeRestrictedInt8s>(), //
        make_unique<WriteUnitTestingRangeRestrictedInt8s>(), //
        make_unique<SubscribeAttributeUnitTestingRangeRestrictedInt8s>(), //
        make_unique<ReadUnitTestingRangeRestrictedInt16u>(), //
        make_unique<WriteUnitTestingRangeRestrictedInt16u>(), //
        make_unique<SubscribeAttributeUnitTestingRangeRestrictedInt16u>(), //
        make_unique<ReadUnitTestingRangeRestrictedInt16s>(), //
        make_unique<WriteUnitTestingRangeRestrictedInt16s>(), //
        make_unique<SubscribeAttributeUnitTestingRangeRestrictedInt16s>(), //
        make_unique<ReadUnitTestingListLongOctetString>(), //
        make_unique<WriteUnitTestingListLongOctetString>(), //
        make_unique<SubscribeAttributeUnitTestingListLongOctetString>(), //
        make_unique<ReadUnitTestingListFabricScoped>(), //
        make_unique<WriteUnitTestingListFabricScoped>(), //
        make_unique<SubscribeAttributeUnitTestingListFabricScoped>(), //
        make_unique<ReadUnitTestingTimedWriteBoolean>(), //
        make_unique<WriteUnitTestingTimedWriteBoolean>(), //
        make_unique<SubscribeAttributeUnitTestingTimedWriteBoolean>(), //
        make_unique<ReadUnitTestingGeneralErrorBoolean>(), //
        make_unique<WriteUnitTestingGeneralErrorBoolean>(), //
        make_unique<SubscribeAttributeUnitTestingGeneralErrorBoolean>(), //
        make_unique<ReadUnitTestingClusterErrorBoolean>(), //
        make_unique<WriteUnitTestingClusterErrorBoolean>(), //
        make_unique<SubscribeAttributeUnitTestingClusterErrorBoolean>(), //
        make_unique<ReadUnitTestingUnsupported>(), //
        make_unique<WriteUnitTestingUnsupported>(), //
        make_unique<SubscribeAttributeUnitTestingUnsupported>(), //
        make_unique<ReadUnitTestingNullableBoolean>(), //
        make_unique<WriteUnitTestingNullableBoolean>(), //
        make_unique<SubscribeAttributeUnitTestingNullableBoolean>(), //
        make_unique<ReadUnitTestingNullableBitmap8>(), //
        make_unique<WriteUnitTestingNullableBitmap8>(), //
        make_unique<SubscribeAttributeUnitTestingNullableBitmap8>(), //
        make_unique<ReadUnitTestingNullableBitmap16>(), //
        make_unique<WriteUnitTestingNullableBitmap16>(), //
        make_unique<SubscribeAttributeUnitTestingNullableBitmap16>(), //
        make_unique<ReadUnitTestingNullableBitmap32>(), //
        make_unique<WriteUnitTestingNullableBitmap32>(), //
        make_unique<SubscribeAttributeUnitTestingNullableBitmap32>(), //
        make_unique<ReadUnitTestingNullableBitmap64>(), //
        make_unique<WriteUnitTestingNullableBitmap64>(), //
        make_unique<SubscribeAttributeUnitTestingNullableBitmap64>(), //
        make_unique<ReadUnitTestingNullableInt8u>(), //
        make_unique<WriteUnitTestingNullableInt8u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt8u>(), //
        make_unique<ReadUnitTestingNullableInt16u>(), //
        make_unique<WriteUnitTestingNullableInt16u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt16u>(), //
        make_unique<ReadUnitTestingNullableInt24u>(), //
        make_unique<WriteUnitTestingNullableInt24u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt24u>(), //
        make_unique<ReadUnitTestingNullableInt32u>(), //
        make_unique<WriteUnitTestingNullableInt32u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt32u>(), //
        make_unique<ReadUnitTestingNullableInt40u>(), //
        make_unique<WriteUnitTestingNullableInt40u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt40u>(), //
        make_unique<ReadUnitTestingNullableInt48u>(), //
        make_unique<WriteUnitTestingNullableInt48u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt48u>(), //
        make_unique<ReadUnitTestingNullableInt56u>(), //
        make_unique<WriteUnitTestingNullableInt56u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt56u>(), //
        make_unique<ReadUnitTestingNullableInt64u>(), //
        make_unique<WriteUnitTestingNullableInt64u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt64u>(), //
        make_unique<ReadUnitTestingNullableInt8s>(), //
        make_unique<WriteUnitTestingNullableInt8s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt8s>(), //
        make_unique<ReadUnitTestingNullableInt16s>(), //
        make_unique<WriteUnitTestingNullableInt16s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt16s>(), //
        make_unique<ReadUnitTestingNullableInt24s>(), //
        make_unique<WriteUnitTestingNullableInt24s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt24s>(), //
        make_unique<ReadUnitTestingNullableInt32s>(), //
        make_unique<WriteUnitTestingNullableInt32s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt32s>(), //
        make_unique<ReadUnitTestingNullableInt40s>(), //
        make_unique<WriteUnitTestingNullableInt40s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt40s>(), //
        make_unique<ReadUnitTestingNullableInt48s>(), //
        make_unique<WriteUnitTestingNullableInt48s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt48s>(), //
        make_unique<ReadUnitTestingNullableInt56s>(), //
        make_unique<WriteUnitTestingNullableInt56s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt56s>(), //
        make_unique<ReadUnitTestingNullableInt64s>(), //
        make_unique<WriteUnitTestingNullableInt64s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableInt64s>(), //
        make_unique<ReadUnitTestingNullableEnum8>(), //
        make_unique<WriteUnitTestingNullableEnum8>(), //
        make_unique<SubscribeAttributeUnitTestingNullableEnum8>(), //
        make_unique<ReadUnitTestingNullableEnum16>(), //
        make_unique<WriteUnitTestingNullableEnum16>(), //
        make_unique<SubscribeAttributeUnitTestingNullableEnum16>(), //
        make_unique<ReadUnitTestingNullableFloatSingle>(), //
        make_unique<WriteUnitTestingNullableFloatSingle>(), //
        make_unique<SubscribeAttributeUnitTestingNullableFloatSingle>(), //
        make_unique<ReadUnitTestingNullableFloatDouble>(), //
        make_unique<WriteUnitTestingNullableFloatDouble>(), //
        make_unique<SubscribeAttributeUnitTestingNullableFloatDouble>(), //
        make_unique<ReadUnitTestingNullableOctetString>(), //
        make_unique<WriteUnitTestingNullableOctetString>(), //
        make_unique<SubscribeAttributeUnitTestingNullableOctetString>(), //
        make_unique<ReadUnitTestingNullableCharString>(), //
        make_unique<WriteUnitTestingNullableCharString>(), //
        make_unique<SubscribeAttributeUnitTestingNullableCharString>(), //
        make_unique<ReadUnitTestingNullableEnumAttr>(), //
        make_unique<WriteUnitTestingNullableEnumAttr>(), //
        make_unique<SubscribeAttributeUnitTestingNullableEnumAttr>(), //
        make_unique<ReadUnitTestingNullableStruct>(), //
        make_unique<WriteUnitTestingNullableStruct>(), //
        make_unique<SubscribeAttributeUnitTestingNullableStruct>(), //
        make_unique<ReadUnitTestingNullableRangeRestrictedInt8u>(), //
        make_unique<WriteUnitTestingNullableRangeRestrictedInt8u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableRangeRestrictedInt8u>(), //
        make_unique<ReadUnitTestingNullableRangeRestrictedInt8s>(), //
        make_unique<WriteUnitTestingNullableRangeRestrictedInt8s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableRangeRestrictedInt8s>(), //
        make_unique<ReadUnitTestingNullableRangeRestrictedInt16u>(), //
        make_unique<WriteUnitTestingNullableRangeRestrictedInt16u>(), //
        make_unique<SubscribeAttributeUnitTestingNullableRangeRestrictedInt16u>(), //
        make_unique<ReadUnitTestingNullableRangeRestrictedInt16s>(), //
        make_unique<WriteUnitTestingNullableRangeRestrictedInt16s>(), //
        make_unique<SubscribeAttributeUnitTestingNullableRangeRestrictedInt16s>(), //
        make_unique<ReadUnitTestingWriteOnlyInt8u>(), //
        make_unique<WriteUnitTestingWriteOnlyInt8u>(), //
        make_unique<SubscribeAttributeUnitTestingWriteOnlyInt8u>(), //
        make_unique<ReadUnitTestingGeneratedCommandList>(), //
        make_unique<SubscribeAttributeUnitTestingGeneratedCommandList>(), //
        make_unique<ReadUnitTestingAcceptedCommandList>(), //
        make_unique<SubscribeAttributeUnitTestingAcceptedCommandList>(), //
        make_unique<ReadUnitTestingAttributeList>(), //
        make_unique<SubscribeAttributeUnitTestingAttributeList>(), //
        make_unique<ReadUnitTestingFeatureMap>(), //
        make_unique<SubscribeAttributeUnitTestingFeatureMap>(), //
        make_unique<ReadUnitTestingClusterRevision>(), //
        make_unique<SubscribeAttributeUnitTestingClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    commands.Register(clusterName, clusterCommands);
}

void registerClusterAny(Commands & commands)
{
    const char * clusterName = "Any";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(), //
        make_unique<ReadAttribute>(), //
        make_unique<WriteAttribute>(), //
        make_unique<SubscribeAttribute>(), //
        make_unique<ReadEvent>(), //
        make_unique<SubscribeEvent>(chip::kInvalidClusterId, true), //
        make_unique<SubscribeEvent>(), //
    };

    commands.Register(clusterName, clusterCommands);
}

void registerClusters(Commands & commands)
{
    registerClusterAny(commands);
    registerClusterIdentify(commands);
    registerClusterGroups(commands);
    registerClusterScenes(commands);
    registerClusterOnOff(commands);
    registerClusterOnOffSwitchConfiguration(commands);
    registerClusterLevelControl(commands);
    registerClusterBinaryInputBasic(commands);
    registerClusterDescriptor(commands);
    registerClusterBinding(commands);
    registerClusterAccessControl(commands);
    registerClusterActions(commands);
    registerClusterBasicInformation(commands);
    registerClusterOtaSoftwareUpdateProvider(commands);
    registerClusterOtaSoftwareUpdateRequestor(commands);
    registerClusterLocalizationConfiguration(commands);
    registerClusterTimeFormatLocalization(commands);
    registerClusterUnitLocalization(commands);
    registerClusterPowerSourceConfiguration(commands);
    registerClusterPowerSource(commands);
    registerClusterGeneralCommissioning(commands);
    registerClusterNetworkCommissioning(commands);
    registerClusterDiagnosticLogs(commands);
    registerClusterGeneralDiagnostics(commands);
    registerClusterSoftwareDiagnostics(commands);
    registerClusterThreadNetworkDiagnostics(commands);
    registerClusterWiFiNetworkDiagnostics(commands);
    registerClusterEthernetNetworkDiagnostics(commands);
    registerClusterBridgedDeviceBasicInformation(commands);
    registerClusterSwitch(commands);
    registerClusterAdministratorCommissioning(commands);
    registerClusterOperationalCredentials(commands);
    registerClusterGroupKeyManagement(commands);
    registerClusterFixedLabel(commands);
    registerClusterUserLabel(commands);
    registerClusterBooleanState(commands);
    registerClusterModeSelect(commands);
    registerClusterHepaFilterMonitoring(commands);
    registerClusterActivatedCarbonFilterMonitoring(commands);
    registerClusterCeramicFilterMonitoring(commands);
    registerClusterElectrostaticFilterMonitoring(commands);
    registerClusterUvFilterMonitoring(commands);
    registerClusterIonizingFilterMonitoring(commands);
    registerClusterZeoliteFilterMonitoring(commands);
    registerClusterOzoneFilterMonitoring(commands);
    registerClusterWaterTankMonitoring(commands);
    registerClusterFuelTankMonitoring(commands);
    registerClusterInkCartridgeMonitoring(commands);
    registerClusterTonerCartridgeMonitoring(commands);
    registerClusterDoorLock(commands);
    registerClusterWindowCovering(commands);
    registerClusterBarrierControl(commands);
    registerClusterPumpConfigurationAndControl(commands);
    registerClusterThermostat(commands);
    registerClusterFanControl(commands);
    registerClusterThermostatUserInterfaceConfiguration(commands);
    registerClusterColorControl(commands);
    registerClusterBallastConfiguration(commands);
    registerClusterIlluminanceMeasurement(commands);
    registerClusterTemperatureMeasurement(commands);
    registerClusterPressureMeasurement(commands);
    registerClusterFlowMeasurement(commands);
    registerClusterRelativeHumidityMeasurement(commands);
    registerClusterOccupancySensing(commands);
    registerClusterWakeOnLan(commands);
    registerClusterChannel(commands);
    registerClusterTargetNavigator(commands);
    registerClusterMediaPlayback(commands);
    registerClusterMediaInput(commands);
    registerClusterLowPower(commands);
    registerClusterKeypadInput(commands);
    registerClusterContentLauncher(commands);
    registerClusterAudioOutput(commands);
    registerClusterApplicationLauncher(commands);
    registerClusterApplicationBasic(commands);
    registerClusterAccountLogin(commands);
    registerClusterElectricalMeasurement(commands);
    registerClusterUnitTesting(commands);
}
