/*
 *
 *    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 |
| IcdManagement                                                       | 0x0046 |
| ModeSelect                                                          | 0x0050 |
| AirQuality                                                          | 0x005B |
| SmokeCoAlarm                                                        | 0x005C |
| 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 |
| 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 EventList
 */
class ReadIdentifyEventList : public ReadAttribute {
public:
    ReadIdentifyEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadIdentifyEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Identify.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Identify EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIdentifyEventList : public SubscribeAttribute {
public:
    SubscribeAttributeIdentifyEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeIdentifyEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000003) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Identify.EventList 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 EventList
 */
class ReadGroupsEventList : public ReadAttribute {
public:
    ReadGroupsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadGroupsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Groups.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Groups EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeGroupsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000004) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Groups.EventList 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 EventList
 */
class ReadScenesEventList : public ReadAttribute {
public:
    ReadScenesEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadScenesEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Scenes.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Scenes EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeScenesEventList : public SubscribeAttribute {
public:
    SubscribeAttributeScenesEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeScenesEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000005) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Scenes.EventList 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 EventList
 */
class ReadOnOffEventList : public ReadAttribute {
public:
    ReadOnOffEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadOnOffEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOff.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOff EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffEventList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeOnOffEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000006) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOff.EventList 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 EventList
 */
class ReadOnOffSwitchConfigurationEventList : public ReadAttribute {
public:
    ReadOnOffSwitchConfigurationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadOnOffSwitchConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OnOffSwitchConfiguration.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("OnOffSwitchConfiguration EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOnOffSwitchConfigurationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeOnOffSwitchConfigurationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeOnOffSwitchConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000007) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OnOffSwitchConfiguration.EventList 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 EventList
 */
class ReadLevelControlEventList : public ReadAttribute {
public:
    ReadLevelControlEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadLevelControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LevelControl.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("LevelControl EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLevelControlEventList : public SubscribeAttribute {
public:
    SubscribeAttributeLevelControlEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeLevelControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000008) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LevelControl.EventList 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 EventList
 */
class ReadBinaryInputBasicEventList : public ReadAttribute {
public:
    ReadBinaryInputBasicEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadBinaryInputBasicEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BinaryInputBasic.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("BinaryInputBasic EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBinaryInputBasicEventList : public SubscribeAttribute {
public:
    SubscribeAttributeBinaryInputBasicEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeBinaryInputBasicEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000000F) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BinaryInputBasic.EventList 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 EventList
 */
class ReadDescriptorEventList : public ReadAttribute {
public:
    ReadDescriptorEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadDescriptorEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Descriptor.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Descriptor EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDescriptorEventList : public SubscribeAttribute {
public:
    SubscribeAttributeDescriptorEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeDescriptorEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001D) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Descriptor.EventList 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 EventList
 */
class ReadBindingEventList : public ReadAttribute {
public:
    ReadBindingEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadBindingEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Binding.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Binding EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBindingEventList : public SubscribeAttribute {
public:
    SubscribeAttributeBindingEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeBindingEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001E) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Binding.EventList 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 EventList
 */
class ReadAccessControlEventList : public ReadAttribute {
public:
    ReadAccessControlEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadAccessControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccessControl.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccessControl EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccessControlEventList : public SubscribeAttribute {
public:
    SubscribeAttributeAccessControlEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeAccessControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000001F) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccessControl.EventList 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 EventList
 */
class ReadActionsEventList : public ReadAttribute {
public:
    ReadActionsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadActionsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Actions.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Actions EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeActionsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeActionsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeActionsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000025) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Actions.EventList 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 EventList
 */
class ReadBasicInformationEventList : public ReadAttribute {
public:
    ReadBasicInformationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadBasicInformationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BasicInformation.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("BasicInformation EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBasicInformationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeBasicInformationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeBasicInformationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000028) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BasicInformation.EventList 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 EventList
 */
class ReadOtaSoftwareUpdateProviderEventList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateProviderEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadOtaSoftwareUpdateProviderEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateProvider.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateProvider EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateProviderEventList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateProviderEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateProviderEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000029) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateProvider.EventList 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 EventList
 */
class ReadOtaSoftwareUpdateRequestorEventList : public ReadAttribute {
public:
    ReadOtaSoftwareUpdateRequestorEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadOtaSoftwareUpdateRequestorEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OTASoftwareUpdateRequestor.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("OTASoftwareUpdateRequestor EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOtaSoftwareUpdateRequestorEventList : public SubscribeAttribute {
public:
    SubscribeAttributeOtaSoftwareUpdateRequestorEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeOtaSoftwareUpdateRequestorEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002A) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OTASoftwareUpdateRequestor.EventList 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 EventList
 */
class ReadLocalizationConfigurationEventList : public ReadAttribute {
public:
    ReadLocalizationConfigurationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadLocalizationConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LocalizationConfiguration.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("LocalizationConfiguration EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLocalizationConfigurationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeLocalizationConfigurationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeLocalizationConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002B) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LocalizationConfiguration.EventList 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 EventList
 */
class ReadTimeFormatLocalizationEventList : public ReadAttribute {
public:
    ReadTimeFormatLocalizationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadTimeFormatLocalizationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TimeFormatLocalization.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("TimeFormatLocalization EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTimeFormatLocalizationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeTimeFormatLocalizationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeTimeFormatLocalizationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002C) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TimeFormatLocalization.EventList 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 EventList
 */
class ReadUnitLocalizationEventList : public ReadAttribute {
public:
    ReadUnitLocalizationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadUnitLocalizationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitLocalization.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitLocalization EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitLocalizationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitLocalizationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeUnitLocalizationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002D) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitLocalization.EventList 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 EventList
 */
class ReadPowerSourceConfigurationEventList : public ReadAttribute {
public:
    ReadPowerSourceConfigurationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadPowerSourceConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSourceConfiguration.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSourceConfiguration EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceConfigurationEventList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceConfigurationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributePowerSourceConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002E) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSourceConfiguration.EventList 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 EventList
 */
class ReadPowerSourceEventList : public ReadAttribute {
public:
    ReadPowerSourceEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadPowerSourceEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PowerSource.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("PowerSource EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePowerSourceEventList : public SubscribeAttribute {
public:
    SubscribeAttributePowerSourceEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributePowerSourceEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000002F) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PowerSource.EventList 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 EventList
 */
class ReadGeneralCommissioningEventList : public ReadAttribute {
public:
    ReadGeneralCommissioningEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadGeneralCommissioningEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralCommissioning.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralCommissioning EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralCommissioningEventList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralCommissioningEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeGeneralCommissioningEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000030) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralCommissioning.EventList 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 EventList
 */
class ReadNetworkCommissioningEventList : public ReadAttribute {
public:
    ReadNetworkCommissioningEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadNetworkCommissioningEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"NetworkCommissioning.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("NetworkCommissioning EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeNetworkCommissioningEventList : public SubscribeAttribute {
public:
    SubscribeAttributeNetworkCommissioningEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeNetworkCommissioningEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000031) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"NetworkCommissioning.EventList 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 EventList
 */
class ReadDiagnosticLogsEventList : public ReadAttribute {
public:
    ReadDiagnosticLogsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadDiagnosticLogsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DiagnosticLogs.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("DiagnosticLogs EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDiagnosticLogsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeDiagnosticLogsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeDiagnosticLogsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000032) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DiagnosticLogs.EventList 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 EventList
 */
class ReadGeneralDiagnosticsEventList : public ReadAttribute {
public:
    ReadGeneralDiagnosticsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadGeneralDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GeneralDiagnostics.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("GeneralDiagnostics EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGeneralDiagnosticsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeGeneralDiagnosticsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeGeneralDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000033) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GeneralDiagnostics.EventList 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 EventList
 */
class ReadSoftwareDiagnosticsEventList : public ReadAttribute {
public:
    ReadSoftwareDiagnosticsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadSoftwareDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"SoftwareDiagnostics.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("SoftwareDiagnostics EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSoftwareDiagnosticsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeSoftwareDiagnosticsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeSoftwareDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000034) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"SoftwareDiagnostics.EventList 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 EventList
 */
class ReadThreadNetworkDiagnosticsEventList : public ReadAttribute {
public:
    ReadThreadNetworkDiagnosticsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadThreadNetworkDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThreadNetworkDiagnostics.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThreadNetworkDiagnostics EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThreadNetworkDiagnosticsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeThreadNetworkDiagnosticsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeThreadNetworkDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000035) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThreadNetworkDiagnostics.EventList 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 EventList
 */
class ReadWiFiNetworkDiagnosticsEventList : public ReadAttribute {
public:
    ReadWiFiNetworkDiagnosticsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadWiFiNetworkDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WiFiNetworkDiagnostics.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("WiFiNetworkDiagnostics EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWiFiNetworkDiagnosticsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeWiFiNetworkDiagnosticsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeWiFiNetworkDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000036) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WiFiNetworkDiagnostics.EventList 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 EventList
 */
class ReadEthernetNetworkDiagnosticsEventList : public ReadAttribute {
public:
    ReadEthernetNetworkDiagnosticsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadEthernetNetworkDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"EthernetNetworkDiagnostics.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("EthernetNetworkDiagnostics EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeEthernetNetworkDiagnosticsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeEthernetNetworkDiagnosticsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeEthernetNetworkDiagnosticsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000037) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"EthernetNetworkDiagnostics.EventList 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 EventList
 */
class ReadBridgedDeviceBasicInformationEventList : public ReadAttribute {
public:
    ReadBridgedDeviceBasicInformationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadBridgedDeviceBasicInformationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BridgedDeviceBasicInformation.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("BridgedDeviceBasicInformation EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBridgedDeviceBasicInformationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeBridgedDeviceBasicInformationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeBridgedDeviceBasicInformationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000039) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BridgedDeviceBasicInformation.EventList 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 EventList
 */
class ReadSwitchEventList : public ReadAttribute {
public:
    ReadSwitchEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadSwitchEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Switch.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Switch EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeSwitchEventList : public SubscribeAttribute {
public:
    SubscribeAttributeSwitchEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeSwitchEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003B) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Switch.EventList 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 EventList
 */
class ReadAdministratorCommissioningEventList : public ReadAttribute {
public:
    ReadAdministratorCommissioningEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadAdministratorCommissioningEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AdministratorCommissioning.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("AdministratorCommissioning EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAdministratorCommissioningEventList : public SubscribeAttribute {
public:
    SubscribeAttributeAdministratorCommissioningEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeAdministratorCommissioningEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003C) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AdministratorCommissioning.EventList 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 EventList
 */
class ReadOperationalCredentialsEventList : public ReadAttribute {
public:
    ReadOperationalCredentialsEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadOperationalCredentialsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OperationalCredentials.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("OperationalCredentials EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOperationalCredentialsEventList : public SubscribeAttribute {
public:
    SubscribeAttributeOperationalCredentialsEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeOperationalCredentialsEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003E) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OperationalCredentials.EventList 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 EventList
 */
class ReadGroupKeyManagementEventList : public ReadAttribute {
public:
    ReadGroupKeyManagementEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadGroupKeyManagementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"GroupKeyManagement.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("GroupKeyManagement EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeGroupKeyManagementEventList : public SubscribeAttribute {
public:
    SubscribeAttributeGroupKeyManagementEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeGroupKeyManagementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000003F) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"GroupKeyManagement.EventList 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 EventList
 */
class ReadFixedLabelEventList : public ReadAttribute {
public:
    ReadFixedLabelEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadFixedLabelEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FixedLabel.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("FixedLabel EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFixedLabelEventList : public SubscribeAttribute {
public:
    SubscribeAttributeFixedLabelEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeFixedLabelEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000040) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FixedLabel.EventList 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 EventList
 */
class ReadUserLabelEventList : public ReadAttribute {
public:
    ReadUserLabelEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadUserLabelEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UserLabel.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("UserLabel EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUserLabelEventList : public SubscribeAttribute {
public:
    SubscribeAttributeUserLabelEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeUserLabelEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000041) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UserLabel.EventList 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 EventList
 */
class ReadBooleanStateEventList : public ReadAttribute {
public:
    ReadBooleanStateEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadBooleanStateEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BooleanState.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("BooleanState EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBooleanStateEventList : public SubscribeAttribute {
public:
    SubscribeAttributeBooleanStateEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeBooleanStateEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000045) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BooleanState.EventList 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 EventList
 */
class ReadModeSelectEventList : public ReadAttribute {
public:
    ReadModeSelectEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadModeSelectEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ModeSelect.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ModeSelect EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeModeSelectEventList : public SubscribeAttribute {
public:
    SubscribeAttributeModeSelectEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeModeSelectEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000050) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ModeSelect.EventList 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 AirQuality                                                  | 0x005B |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * AirQuality                                                        | 0x0000 |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
\*----------------------------------------------------------------------------*/

/*
 * Attribute AirQuality
 */
class ReadAirQualityAirQuality : public ReadAttribute {
public:
    ReadAirQualityAirQuality()
        : ReadAttribute("air-quality")
    {
    }

    ~ReadAirQualityAirQuality() {}

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

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

class SubscribeAttributeAirQualityAirQuality : public SubscribeAttribute {
public:
    SubscribeAttributeAirQualityAirQuality()
        : SubscribeAttribute("air-quality")
    {
    }

    ~SubscribeAttributeAirQualityAirQuality() {}

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

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadAirQualityGeneratedCommandList() {}

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

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

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

    ~SubscribeAttributeAirQualityGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005B) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"AirQuality.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadAirQualityAcceptedCommandList() {}

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

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

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

    ~SubscribeAttributeAirQualityAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005B) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"AirQuality.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadAirQualityEventList : public ReadAttribute {
public:
    ReadAirQualityEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadAirQualityEventList() {}

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

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

class SubscribeAttributeAirQualityEventList : public SubscribeAttribute {
public:
    SubscribeAttributeAirQualityEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeAirQualityEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005B) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"AirQuality.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadAirQualityAttributeList() {}

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

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

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

    ~SubscribeAttributeAirQualityAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005B) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"AirQuality.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadAirQualityFeatureMap() {}

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

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

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

    ~SubscribeAttributeAirQualityFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005B) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"AirQuality.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadAirQualityClusterRevision() {}

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

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

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

    ~SubscribeAttributeAirQualityClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005B) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device
                                                                      endpointID:@(endpointId)
                                                                           queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"AirQuality.ClusterRevision response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*----------------------------------------------------------------------------*\
| Cluster SmokeCoAlarm                                                | 0x005C |
|------------------------------------------------------------------------------|
| Commands:                                                           |        |
| * SelfTestRequest                                                   |   0x00 |
|------------------------------------------------------------------------------|
| Attributes:                                                         |        |
| * ExpressedState                                                    | 0x0000 |
| * SmokeState                                                        | 0x0001 |
| * COState                                                           | 0x0002 |
| * BatteryAlert                                                      | 0x0003 |
| * DeviceMuted                                                       | 0x0004 |
| * TestInProgress                                                    | 0x0005 |
| * HardwareFaultAlert                                                | 0x0006 |
| * EndOfServiceAlert                                                 | 0x0007 |
| * InterconnectSmokeAlarm                                            | 0x0008 |
| * InterconnectCOAlarm                                               | 0x0009 |
| * ContaminationState                                                | 0x000A |
| * SensitivityLevel                                                  | 0x000B |
| * GeneratedCommandList                                              | 0xFFF8 |
| * AcceptedCommandList                                               | 0xFFF9 |
| * EventList                                                         | 0xFFFA |
| * AttributeList                                                     | 0xFFFB |
| * FeatureMap                                                        | 0xFFFC |
| * ClusterRevision                                                   | 0xFFFD |
|------------------------------------------------------------------------------|
| Events:                                                             |        |
| * SmokeAlarm                                                        | 0x0000 |
| * COAlarm                                                           | 0x0001 |
| * LowBattery                                                        | 0x0002 |
| * HardwareFault                                                     | 0x0003 |
| * EndOfService                                                      | 0x0004 |
| * SelfTestComplete                                                  | 0x0005 |
| * AlarmMuted                                                        | 0x0006 |
| * MuteEnded                                                         | 0x0007 |
| * InterconnectSmokeAlarm                                            | 0x0008 |
| * InterconnectCOAlarm                                               | 0x0009 |
| * AllClear                                                          | 0x000A |
\*----------------------------------------------------------------------------*/

/*
 * Command SelfTestRequest
 */
class SmokeCoAlarmSelfTestRequest : public ClusterCommand {
public:
    SmokeCoAlarmSelfTestRequest()
        : ClusterCommand("self-test-request")
    {
        ClusterCommand::AddArguments();
    }

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

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSmokeCOAlarmClusterSelfTestRequestParams 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 selfTestRequestWithParams: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 ExpressedState
 */
class ReadSmokeCoAlarmExpressedState : public ReadAttribute {
public:
    ReadSmokeCoAlarmExpressedState()
        : ReadAttribute("expressed-state")
    {
    }

    ~ReadSmokeCoAlarmExpressedState() {}

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

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

class SubscribeAttributeSmokeCoAlarmExpressedState : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmExpressedState()
        : SubscribeAttribute("expressed-state")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmExpressedState() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SmokeState
 */
class ReadSmokeCoAlarmSmokeState : public ReadAttribute {
public:
    ReadSmokeCoAlarmSmokeState()
        : ReadAttribute("smoke-state")
    {
    }

    ~ReadSmokeCoAlarmSmokeState() {}

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

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

class SubscribeAttributeSmokeCoAlarmSmokeState : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmSmokeState()
        : SubscribeAttribute("smoke-state")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmSmokeState() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute COState
 */
class ReadSmokeCoAlarmCOState : public ReadAttribute {
public:
    ReadSmokeCoAlarmCOState()
        : ReadAttribute("costate")
    {
    }

    ~ReadSmokeCoAlarmCOState() {}

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

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

class SubscribeAttributeSmokeCoAlarmCOState : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmCOState()
        : SubscribeAttribute("costate")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmCOState() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute BatteryAlert
 */
class ReadSmokeCoAlarmBatteryAlert : public ReadAttribute {
public:
    ReadSmokeCoAlarmBatteryAlert()
        : ReadAttribute("battery-alert")
    {
    }

    ~ReadSmokeCoAlarmBatteryAlert() {}

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

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

class SubscribeAttributeSmokeCoAlarmBatteryAlert : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmBatteryAlert()
        : SubscribeAttribute("battery-alert")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmBatteryAlert() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute DeviceMuted
 */
class ReadSmokeCoAlarmDeviceMuted : public ReadAttribute {
public:
    ReadSmokeCoAlarmDeviceMuted()
        : ReadAttribute("device-muted")
    {
    }

    ~ReadSmokeCoAlarmDeviceMuted() {}

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

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

class SubscribeAttributeSmokeCoAlarmDeviceMuted : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmDeviceMuted()
        : SubscribeAttribute("device-muted")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmDeviceMuted() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute TestInProgress
 */
class ReadSmokeCoAlarmTestInProgress : public ReadAttribute {
public:
    ReadSmokeCoAlarmTestInProgress()
        : ReadAttribute("test-in-progress")
    {
    }

    ~ReadSmokeCoAlarmTestInProgress() {}

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

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

class SubscribeAttributeSmokeCoAlarmTestInProgress : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmTestInProgress()
        : SubscribeAttribute("test-in-progress")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmTestInProgress() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute HardwareFaultAlert
 */
class ReadSmokeCoAlarmHardwareFaultAlert : public ReadAttribute {
public:
    ReadSmokeCoAlarmHardwareFaultAlert()
        : ReadAttribute("hardware-fault-alert")
    {
    }

    ~ReadSmokeCoAlarmHardwareFaultAlert() {}

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

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

class SubscribeAttributeSmokeCoAlarmHardwareFaultAlert : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmHardwareFaultAlert()
        : SubscribeAttribute("hardware-fault-alert")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmHardwareFaultAlert() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EndOfServiceAlert
 */
class ReadSmokeCoAlarmEndOfServiceAlert : public ReadAttribute {
public:
    ReadSmokeCoAlarmEndOfServiceAlert()
        : ReadAttribute("end-of-service-alert")
    {
    }

    ~ReadSmokeCoAlarmEndOfServiceAlert() {}

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

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

class SubscribeAttributeSmokeCoAlarmEndOfServiceAlert : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmEndOfServiceAlert()
        : SubscribeAttribute("end-of-service-alert")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmEndOfServiceAlert() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InterconnectSmokeAlarm
 */
class ReadSmokeCoAlarmInterconnectSmokeAlarm : public ReadAttribute {
public:
    ReadSmokeCoAlarmInterconnectSmokeAlarm()
        : ReadAttribute("interconnect-smoke-alarm")
    {
    }

    ~ReadSmokeCoAlarmInterconnectSmokeAlarm() {}

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

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

class SubscribeAttributeSmokeCoAlarmInterconnectSmokeAlarm : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmInterconnectSmokeAlarm()
        : SubscribeAttribute("interconnect-smoke-alarm")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmInterconnectSmokeAlarm() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute InterconnectCOAlarm
 */
class ReadSmokeCoAlarmInterconnectCOAlarm : public ReadAttribute {
public:
    ReadSmokeCoAlarmInterconnectCOAlarm()
        : ReadAttribute("interconnect-coalarm")
    {
    }

    ~ReadSmokeCoAlarmInterconnectCOAlarm() {}

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

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

class SubscribeAttributeSmokeCoAlarmInterconnectCOAlarm : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmInterconnectCOAlarm()
        : SubscribeAttribute("interconnect-coalarm")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmInterconnectCOAlarm() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute ContaminationState
 */
class ReadSmokeCoAlarmContaminationState : public ReadAttribute {
public:
    ReadSmokeCoAlarmContaminationState()
        : ReadAttribute("contamination-state")
    {
    }

    ~ReadSmokeCoAlarmContaminationState() {}

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

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

class SubscribeAttributeSmokeCoAlarmContaminationState : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmContaminationState()
        : SubscribeAttribute("contamination-state")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmContaminationState() {}

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

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute SensitivityLevel
 */
class ReadSmokeCoAlarmSensitivityLevel : public ReadAttribute {
public:
    ReadSmokeCoAlarmSensitivityLevel()
        : ReadAttribute("sensitivity-level")
    {
    }

    ~ReadSmokeCoAlarmSensitivityLevel() {}

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

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

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

    ~WriteSmokeCoAlarmSensitivityLevel() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005C) WriteAttribute (0x0000000B) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm 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 writeAttributeSensitivityLevelWithValue:value
                                                  params:params
                                              completion:^(NSError * _Nullable error) {
                                                  if (error != nil) {
                                                      LogNSError("SmokeCOAlarm SensitivityLevel write Error", error);
                                                  }
                                                  SetCommandExitStatus(error);
                                              }];
        return CHIP_NO_ERROR;
    }

private:
    uint8_t mValue;
};

class SubscribeAttributeSmokeCoAlarmSensitivityLevel : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmSensitivityLevel()
        : SubscribeAttribute("sensitivity-level")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmSensitivityLevel() {}

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

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadSmokeCoAlarmGeneratedCommandList() {}

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

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

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

    ~SubscribeAttributeSmokeCoAlarmGeneratedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005C) ReportAttribute (0x0000FFF8) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"SmokeCOAlarm.GeneratedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadSmokeCoAlarmAcceptedCommandList() {}

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

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

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

    ~SubscribeAttributeSmokeCoAlarmAcceptedCommandList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005C) ReportAttribute (0x0000FFF9) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"SmokeCOAlarm.AcceptedCommandList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

/*
 * Attribute EventList
 */
class ReadSmokeCoAlarmEventList : public ReadAttribute {
public:
    ReadSmokeCoAlarmEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadSmokeCoAlarmEventList() {}

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

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

class SubscribeAttributeSmokeCoAlarmEventList : public SubscribeAttribute {
public:
    SubscribeAttributeSmokeCoAlarmEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeSmokeCoAlarmEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005C) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"SmokeCOAlarm.EventList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadSmokeCoAlarmAttributeList() {}

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

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

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

    ~SubscribeAttributeSmokeCoAlarmAttributeList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005C) ReportAttribute (0x0000FFFB) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"SmokeCOAlarm.AttributeList response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadSmokeCoAlarmFeatureMap() {}

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

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

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

    ~SubscribeAttributeSmokeCoAlarmFeatureMap() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005C) ReportAttribute (0x0000FFFC) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"SmokeCOAlarm.FeatureMap response %@", [value description]);
                SetCommandExitStatus(error);
            }];

        return CHIP_NO_ERROR;
    }
};

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

    ~ReadSmokeCoAlarmClusterRevision() {}

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

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

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

    ~SubscribeAttributeSmokeCoAlarmClusterRevision() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000005C) ReportAttribute (0x0000FFFD) on endpoint %u", endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device
                                                                        endpointID:@(endpointId)
                                                                             queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) 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(@"SmokeCOAlarm.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 |
| * UnboltDoor                                                        |   0x27 |
|------------------------------------------------------------------------------|
| 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;
};

/*
 * Command UnboltDoor
 */
class DoorLockUnboltDoor : public ClusterCommand {
public:
    DoorLockUnboltDoor()
        : ClusterCommand("unbolt-door")
    {
        AddArgument("PINCode", &mRequest.PINCode);
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) command (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 = [[MTRDoorLockClusterUnboltDoorParams 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 unboltDoorWithParams: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::UnboltDoor::Type mRequest;
};

/*
 * 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 EventList
 */
class ReadDoorLockEventList : public ReadAttribute {
public:
    ReadDoorLockEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadDoorLockEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"DoorLock.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("DoorLock EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeDoorLockEventList : public SubscribeAttribute {
public:
    SubscribeAttributeDoorLockEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeDoorLockEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000101) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"DoorLock.EventList 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 EventList
 */
class ReadWindowCoveringEventList : public ReadAttribute {
public:
    ReadWindowCoveringEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadWindowCoveringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WindowCovering.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("WindowCovering EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWindowCoveringEventList : public SubscribeAttribute {
public:
    SubscribeAttributeWindowCoveringEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeWindowCoveringEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000102) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WindowCovering.EventList 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 EventList
 */
class ReadBarrierControlEventList : public ReadAttribute {
public:
    ReadBarrierControlEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadBarrierControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BarrierControl.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("BarrierControl EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBarrierControlEventList : public SubscribeAttribute {
public:
    SubscribeAttributeBarrierControlEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeBarrierControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000103) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BarrierControl.EventList 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 EventList
 */
class ReadPumpConfigurationAndControlEventList : public ReadAttribute {
public:
    ReadPumpConfigurationAndControlEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadPumpConfigurationAndControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PumpConfigurationAndControl.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("PumpConfigurationAndControl EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePumpConfigurationAndControlEventList : public SubscribeAttribute {
public:
    SubscribeAttributePumpConfigurationAndControlEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributePumpConfigurationAndControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000200) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PumpConfigurationAndControl.EventList 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 EventList
 */
class ReadThermostatEventList : public ReadAttribute {
public:
    ReadThermostatEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadThermostatEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Thermostat.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Thermostat EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatEventList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeThermostatEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000201) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Thermostat.EventList 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 EventList
 */
class ReadFanControlEventList : public ReadAttribute {
public:
    ReadFanControlEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadFanControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FanControl.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("FanControl EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFanControlEventList : public SubscribeAttribute {
public:
    SubscribeAttributeFanControlEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeFanControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000202) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FanControl.EventList 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 EventList
 */
class ReadThermostatUserInterfaceConfigurationEventList : public ReadAttribute {
public:
    ReadThermostatUserInterfaceConfigurationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadThermostatUserInterfaceConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ThermostatUserInterfaceConfiguration.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ThermostatUserInterfaceConfiguration EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeThermostatUserInterfaceConfigurationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeThermostatUserInterfaceConfigurationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeThermostatUserInterfaceConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000204) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ThermostatUserInterfaceConfiguration.EventList 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 EventList
 */
class ReadColorControlEventList : public ReadAttribute {
public:
    ReadColorControlEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadColorControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ColorControl.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ColorControl EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeColorControlEventList : public SubscribeAttribute {
public:
    SubscribeAttributeColorControlEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeColorControlEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000300) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ColorControl.EventList 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 EventList
 */
class ReadBallastConfigurationEventList : public ReadAttribute {
public:
    ReadBallastConfigurationEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadBallastConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"BallastConfiguration.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("BallastConfiguration EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeBallastConfigurationEventList : public SubscribeAttribute {
public:
    SubscribeAttributeBallastConfigurationEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeBallastConfigurationEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000301) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"BallastConfiguration.EventList 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 EventList
 */
class ReadIlluminanceMeasurementEventList : public ReadAttribute {
public:
    ReadIlluminanceMeasurementEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadIlluminanceMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"IlluminanceMeasurement.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("IlluminanceMeasurement EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeIlluminanceMeasurementEventList : public SubscribeAttribute {
public:
    SubscribeAttributeIlluminanceMeasurementEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeIlluminanceMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000400) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"IlluminanceMeasurement.EventList 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 EventList
 */
class ReadTemperatureMeasurementEventList : public ReadAttribute {
public:
    ReadTemperatureMeasurementEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadTemperatureMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TemperatureMeasurement.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("TemperatureMeasurement EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTemperatureMeasurementEventList : public SubscribeAttribute {
public:
    SubscribeAttributeTemperatureMeasurementEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeTemperatureMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000402) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TemperatureMeasurement.EventList 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 EventList
 */
class ReadPressureMeasurementEventList : public ReadAttribute {
public:
    ReadPressureMeasurementEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadPressureMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"PressureMeasurement.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("PressureMeasurement EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributePressureMeasurementEventList : public SubscribeAttribute {
public:
    SubscribeAttributePressureMeasurementEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributePressureMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000403) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"PressureMeasurement.EventList 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 EventList
 */
class ReadFlowMeasurementEventList : public ReadAttribute {
public:
    ReadFlowMeasurementEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadFlowMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"FlowMeasurement.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("FlowMeasurement EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeFlowMeasurementEventList : public SubscribeAttribute {
public:
    SubscribeAttributeFlowMeasurementEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeFlowMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000404) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"FlowMeasurement.EventList 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 EventList
 */
class ReadRelativeHumidityMeasurementEventList : public ReadAttribute {
public:
    ReadRelativeHumidityMeasurementEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadRelativeHumidityMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"RelativeHumidityMeasurement.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("RelativeHumidityMeasurement EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeRelativeHumidityMeasurementEventList : public SubscribeAttribute {
public:
    SubscribeAttributeRelativeHumidityMeasurementEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeRelativeHumidityMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000405) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"RelativeHumidityMeasurement.EventList 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 EventList
 */
class ReadOccupancySensingEventList : public ReadAttribute {
public:
    ReadOccupancySensingEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadOccupancySensingEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"OccupancySensing.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("OccupancySensing EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeOccupancySensingEventList : public SubscribeAttribute {
public:
    SubscribeAttributeOccupancySensingEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeOccupancySensingEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000406) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"OccupancySensing.EventList 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 EventList
 */
class ReadWakeOnLanEventList : public ReadAttribute {
public:
    ReadWakeOnLanEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadWakeOnLanEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"WakeOnLAN.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("WakeOnLAN EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeWakeOnLanEventList : public SubscribeAttribute {
public:
    SubscribeAttributeWakeOnLanEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeWakeOnLanEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000503) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"WakeOnLAN.EventList 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 EventList
 */
class ReadChannelEventList : public ReadAttribute {
public:
    ReadChannelEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadChannelEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"Channel.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("Channel EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeChannelEventList : public SubscribeAttribute {
public:
    SubscribeAttributeChannelEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeChannelEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000504) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"Channel.EventList 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 EventList
 */
class ReadTargetNavigatorEventList : public ReadAttribute {
public:
    ReadTargetNavigatorEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadTargetNavigatorEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"TargetNavigator.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("TargetNavigator EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeTargetNavigatorEventList : public SubscribeAttribute {
public:
    SubscribeAttributeTargetNavigatorEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeTargetNavigatorEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000505) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"TargetNavigator.EventList 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 EventList
 */
class ReadMediaPlaybackEventList : public ReadAttribute {
public:
    ReadMediaPlaybackEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadMediaPlaybackEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaPlayback.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaPlayback EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaPlaybackEventList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaPlaybackEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeMediaPlaybackEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000506) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaPlayback.EventList 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 EventList
 */
class ReadMediaInputEventList : public ReadAttribute {
public:
    ReadMediaInputEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadMediaInputEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"MediaInput.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("MediaInput EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeMediaInputEventList : public SubscribeAttribute {
public:
    SubscribeAttributeMediaInputEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeMediaInputEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000507) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"MediaInput.EventList 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 EventList
 */
class ReadLowPowerEventList : public ReadAttribute {
public:
    ReadLowPowerEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadLowPowerEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"LowPower.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("LowPower EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeLowPowerEventList : public SubscribeAttribute {
public:
    SubscribeAttributeLowPowerEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeLowPowerEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000508) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"LowPower.EventList 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 EventList
 */
class ReadKeypadInputEventList : public ReadAttribute {
public:
    ReadKeypadInputEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadKeypadInputEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"KeypadInput.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("KeypadInput EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeKeypadInputEventList : public SubscribeAttribute {
public:
    SubscribeAttributeKeypadInputEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeKeypadInputEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000509) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"KeypadInput.EventList 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 EventList
 */
class ReadContentLauncherEventList : public ReadAttribute {
public:
    ReadContentLauncherEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadContentLauncherEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ContentLauncher.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ContentLauncher EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeContentLauncherEventList : public SubscribeAttribute {
public:
    SubscribeAttributeContentLauncherEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeContentLauncherEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050A) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ContentLauncher.EventList 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 EventList
 */
class ReadAudioOutputEventList : public ReadAttribute {
public:
    ReadAudioOutputEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadAudioOutputEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AudioOutput.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("AudioOutput EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAudioOutputEventList : public SubscribeAttribute {
public:
    SubscribeAttributeAudioOutputEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeAudioOutputEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050B) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AudioOutput.EventList 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 EventList
 */
class ReadApplicationLauncherEventList : public ReadAttribute {
public:
    ReadApplicationLauncherEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadApplicationLauncherEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationLauncher.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationLauncher EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationLauncherEventList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationLauncherEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeApplicationLauncherEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050C) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationLauncher.EventList 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 EventList
 */
class ReadApplicationBasicEventList : public ReadAttribute {
public:
    ReadApplicationBasicEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadApplicationBasicEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ApplicationBasic.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ApplicationBasic EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeApplicationBasicEventList : public SubscribeAttribute {
public:
    SubscribeAttributeApplicationBasicEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeApplicationBasicEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050D) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ApplicationBasic.EventList 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 EventList
 */
class ReadAccountLoginEventList : public ReadAttribute {
public:
    ReadAccountLoginEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadAccountLoginEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReadAttribute (0x0000FFFA) 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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"AccountLogin.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("AccountLogin EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeAccountLoginEventList : public SubscribeAttribute {
public:
    SubscribeAttributeAccountLoginEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeAccountLoginEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x0000050E) ReportAttribute (0x0000FFFA) 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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"AccountLogin.EventList 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 EventList
 */
class ReadElectricalMeasurementEventList : public ReadAttribute {
public:
    ReadElectricalMeasurementEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadElectricalMeasurementEventList() {}

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

        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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"ElectricalMeasurement.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("ElectricalMeasurement EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeElectricalMeasurementEventList : public SubscribeAttribute {
public:
    SubscribeAttributeElectricalMeasurementEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeElectricalMeasurementEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0x00000B04) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"ElectricalMeasurement.EventList 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 EventList
 */
class ReadUnitTestingEventList : public ReadAttribute {
public:
    ReadUnitTestingEventList()
        : ReadAttribute("event-list")
    {
    }

    ~ReadUnitTestingEventList() {}

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

        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 readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) {
            NSLog(@"UnitTesting.EventList response %@", [value description]);
            if (error != nil) {
                LogNSError("UnitTesting EventList read Error", error);
            }
            SetCommandExitStatus(error);
        }];
        return CHIP_NO_ERROR;
    }
};

class SubscribeAttributeUnitTestingEventList : public SubscribeAttribute {
public:
    SubscribeAttributeUnitTestingEventList()
        : SubscribeAttribute("event-list")
    {
    }

    ~SubscribeAttributeUnitTestingEventList() {}

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster (0xFFF1FC05) ReportAttribute (0x0000FFFA) on endpoint %u", endpointId);
        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 subscribeAttributeEventListWithParams:params
            subscriptionEstablished:^() {
                mSubscriptionEstablished = YES;
            }
            reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) {
                NSLog(@"UnitTesting.EventList 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<ReadIdentifyEventList>(), //
        make_unique<SubscribeAttributeIdentifyEventList>(), //
        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<ReadGroupsEventList>(), //
        make_unique<SubscribeAttributeGroupsEventList>(), //
        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<ReadScenesEventList>(), //
        make_unique<SubscribeAttributeScenesEventList>(), //
        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<ReadOnOffEventList>(), //
        make_unique<SubscribeAttributeOnOffEventList>(), //
        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<ReadOnOffSwitchConfigurationEventList>(), //
        make_unique<SubscribeAttributeOnOffSwitchConfigurationEventList>(), //
        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<ReadLevelControlEventList>(), //
        make_unique<SubscribeAttributeLevelControlEventList>(), //
        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<ReadBinaryInputBasicEventList>(), //
        make_unique<SubscribeAttributeBinaryInputBasicEventList>(), //
        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<ReadDescriptorEventList>(), //
        make_unique<SubscribeAttributeDescriptorEventList>(), //
        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<ReadBindingEventList>(), //
        make_unique<SubscribeAttributeBindingEventList>(), //
        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<ReadAccessControlEventList>(), //
        make_unique<SubscribeAttributeAccessControlEventList>(), //
        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<ReadActionsEventList>(), //
        make_unique<SubscribeAttributeActionsEventList>(), //
        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<ReadBasicInformationEventList>(), //
        make_unique<SubscribeAttributeBasicInformationEventList>(), //
        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<ReadOtaSoftwareUpdateProviderEventList>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateProviderEventList>(), //
        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<ReadOtaSoftwareUpdateRequestorEventList>(), //
        make_unique<SubscribeAttributeOtaSoftwareUpdateRequestorEventList>(), //
        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<ReadLocalizationConfigurationEventList>(), //
        make_unique<SubscribeAttributeLocalizationConfigurationEventList>(), //
        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<ReadTimeFormatLocalizationEventList>(), //
        make_unique<SubscribeAttributeTimeFormatLocalizationEventList>(), //
        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<ReadUnitLocalizationEventList>(), //
        make_unique<SubscribeAttributeUnitLocalizationEventList>(), //
        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<ReadPowerSourceConfigurationEventList>(), //
        make_unique<SubscribeAttributePowerSourceConfigurationEventList>(), //
        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<ReadPowerSourceEventList>(), //
        make_unique<SubscribeAttributePowerSourceEventList>(), //
        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<ReadGeneralCommissioningEventList>(), //
        make_unique<SubscribeAttributeGeneralCommissioningEventList>(), //
        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<ReadNetworkCommissioningEventList>(), //
        make_unique<SubscribeAttributeNetworkCommissioningEventList>(), //
        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<ReadDiagnosticLogsEventList>(), //
        make_unique<SubscribeAttributeDiagnosticLogsEventList>(), //
        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<ReadGeneralDiagnosticsEventList>(), //
        make_unique<SubscribeAttributeGeneralDiagnosticsEventList>(), //
        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<ReadSoftwareDiagnosticsEventList>(), //
        make_unique<SubscribeAttributeSoftwareDiagnosticsEventList>(), //
        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<ReadThreadNetworkDiagnosticsEventList>(), //
        make_unique<SubscribeAttributeThreadNetworkDiagnosticsEventList>(), //
        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<ReadWiFiNetworkDiagnosticsEventList>(), //
        make_unique<SubscribeAttributeWiFiNetworkDiagnosticsEventList>(), //
        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<ReadEthernetNetworkDiagnosticsEventList>(), //
        make_unique<SubscribeAttributeEthernetNetworkDiagnosticsEventList>(), //
        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<ReadBridgedDeviceBasicInformationEventList>(), //
        make_unique<SubscribeAttributeBridgedDeviceBasicInformationEventList>(), //
        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<ReadSwitchEventList>(), //
        make_unique<SubscribeAttributeSwitchEventList>(), //
        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<ReadAdministratorCommissioningEventList>(), //
        make_unique<SubscribeAttributeAdministratorCommissioningEventList>(), //
        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<ReadOperationalCredentialsEventList>(), //
        make_unique<SubscribeAttributeOperationalCredentialsEventList>(), //
        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<ReadGroupKeyManagementEventList>(), //
        make_unique<SubscribeAttributeGroupKeyManagementEventList>(), //
        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<ReadFixedLabelEventList>(), //
        make_unique<SubscribeAttributeFixedLabelEventList>(), //
        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<ReadUserLabelEventList>(), //
        make_unique<SubscribeAttributeUserLabelEventList>(), //
        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<ReadBooleanStateEventList>(), //
        make_unique<SubscribeAttributeBooleanStateEventList>(), //
        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<ReadModeSelectEventList>(), //
        make_unique<SubscribeAttributeModeSelectEventList>(), //
        make_unique<ReadModeSelectAttributeList>(), //
        make_unique<SubscribeAttributeModeSelectAttributeList>(), //
        make_unique<ReadModeSelectFeatureMap>(), //
        make_unique<SubscribeAttributeModeSelectFeatureMap>(), //
        make_unique<ReadModeSelectClusterRevision>(), //
        make_unique<SubscribeAttributeModeSelectClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterAirQuality(Commands & commands)
{
    using namespace chip::app::Clusters::AirQuality;

    const char * clusterName = "AirQuality";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadAirQualityAirQuality>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeAirQualityAirQuality>(), //
        make_unique<ReadAirQualityGeneratedCommandList>(), //
        make_unique<SubscribeAttributeAirQualityGeneratedCommandList>(), //
        make_unique<ReadAirQualityAcceptedCommandList>(), //
        make_unique<SubscribeAttributeAirQualityAcceptedCommandList>(), //
        make_unique<ReadAirQualityEventList>(), //
        make_unique<SubscribeAttributeAirQualityEventList>(), //
        make_unique<ReadAirQualityAttributeList>(), //
        make_unique<SubscribeAttributeAirQualityAttributeList>(), //
        make_unique<ReadAirQualityFeatureMap>(), //
        make_unique<SubscribeAttributeAirQualityFeatureMap>(), //
        make_unique<ReadAirQualityClusterRevision>(), //
        make_unique<SubscribeAttributeAirQualityClusterRevision>(), //
    };

    commands.Register(clusterName, clusterCommands);
}
void registerClusterSmokeCoAlarm(Commands & commands)
{
    using namespace chip::app::Clusters::SmokeCoAlarm;

    const char * clusterName = "SmokeCoAlarm";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        make_unique<SmokeCoAlarmSelfTestRequest>(), //
        make_unique<ReadAttribute>(Id), //
        make_unique<ReadSmokeCoAlarmExpressedState>(), //
        make_unique<WriteAttribute>(Id), //
        make_unique<SubscribeAttribute>(Id), //
        make_unique<SubscribeAttributeSmokeCoAlarmExpressedState>(), //
        make_unique<ReadSmokeCoAlarmSmokeState>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmSmokeState>(), //
        make_unique<ReadSmokeCoAlarmCOState>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmCOState>(), //
        make_unique<ReadSmokeCoAlarmBatteryAlert>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmBatteryAlert>(), //
        make_unique<ReadSmokeCoAlarmDeviceMuted>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmDeviceMuted>(), //
        make_unique<ReadSmokeCoAlarmTestInProgress>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmTestInProgress>(), //
        make_unique<ReadSmokeCoAlarmHardwareFaultAlert>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmHardwareFaultAlert>(), //
        make_unique<ReadSmokeCoAlarmEndOfServiceAlert>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmEndOfServiceAlert>(), //
        make_unique<ReadSmokeCoAlarmInterconnectSmokeAlarm>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmInterconnectSmokeAlarm>(), //
        make_unique<ReadSmokeCoAlarmInterconnectCOAlarm>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmInterconnectCOAlarm>(), //
        make_unique<ReadSmokeCoAlarmContaminationState>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmContaminationState>(), //
        make_unique<ReadSmokeCoAlarmSensitivityLevel>(), //
        make_unique<WriteSmokeCoAlarmSensitivityLevel>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmSensitivityLevel>(), //
        make_unique<ReadSmokeCoAlarmGeneratedCommandList>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmGeneratedCommandList>(), //
        make_unique<ReadSmokeCoAlarmAcceptedCommandList>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmAcceptedCommandList>(), //
        make_unique<ReadSmokeCoAlarmEventList>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmEventList>(), //
        make_unique<ReadSmokeCoAlarmAttributeList>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmAttributeList>(), //
        make_unique<ReadSmokeCoAlarmFeatureMap>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmFeatureMap>(), //
        make_unique<ReadSmokeCoAlarmClusterRevision>(), //
        make_unique<SubscribeAttributeSmokeCoAlarmClusterRevision>(), //
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
    };

    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<DoorLockUnboltDoor>(), //
        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<ReadDoorLockEventList>(), //
        make_unique<SubscribeAttributeDoorLockEventList>(), //
        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<ReadWindowCoveringEventList>(), //
        make_unique<SubscribeAttributeWindowCoveringEventList>(), //
        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<ReadBarrierControlEventList>(), //
        make_unique<SubscribeAttributeBarrierControlEventList>(), //
        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<ReadPumpConfigurationAndControlEventList>(), //
        make_unique<SubscribeAttributePumpConfigurationAndControlEventList>(), //
        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<ReadThermostatEventList>(), //
        make_unique<SubscribeAttributeThermostatEventList>(), //
        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<ReadFanControlEventList>(), //
        make_unique<SubscribeAttributeFanControlEventList>(), //
        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<ReadThermostatUserInterfaceConfigurationEventList>(), //
        make_unique<SubscribeAttributeThermostatUserInterfaceConfigurationEventList>(), //
        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<ReadColorControlEventList>(), //
        make_unique<SubscribeAttributeColorControlEventList>(), //
        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<ReadBallastConfigurationEventList>(), //
        make_unique<SubscribeAttributeBallastConfigurationEventList>(), //
        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<ReadIlluminanceMeasurementEventList>(), //
        make_unique<SubscribeAttributeIlluminanceMeasurementEventList>(), //
        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<ReadTemperatureMeasurementEventList>(), //
        make_unique<SubscribeAttributeTemperatureMeasurementEventList>(), //
        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<ReadPressureMeasurementEventList>(), //
        make_unique<SubscribeAttributePressureMeasurementEventList>(), //
        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<ReadFlowMeasurementEventList>(), //
        make_unique<SubscribeAttributeFlowMeasurementEventList>(), //
        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<ReadRelativeHumidityMeasurementEventList>(), //
        make_unique<SubscribeAttributeRelativeHumidityMeasurementEventList>(), //
        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<ReadOccupancySensingEventList>(), //
        make_unique<SubscribeAttributeOccupancySensingEventList>(), //
        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<ReadWakeOnLanEventList>(), //
        make_unique<SubscribeAttributeWakeOnLanEventList>(), //
        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<ReadChannelEventList>(), //
        make_unique<SubscribeAttributeChannelEventList>(), //
        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<ReadTargetNavigatorEventList>(), //
        make_unique<SubscribeAttributeTargetNavigatorEventList>(), //
        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<ReadMediaPlaybackEventList>(), //
        make_unique<SubscribeAttributeMediaPlaybackEventList>(), //
        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<ReadMediaInputEventList>(), //
        make_unique<SubscribeAttributeMediaInputEventList>(), //
        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<ReadLowPowerEventList>(), //
        make_unique<SubscribeAttributeLowPowerEventList>(), //
        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<ReadKeypadInputEventList>(), //
        make_unique<SubscribeAttributeKeypadInputEventList>(), //
        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<ReadContentLauncherEventList>(), //
        make_unique<SubscribeAttributeContentLauncherEventList>(), //
        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<ReadAudioOutputEventList>(), //
        make_unique<SubscribeAttributeAudioOutputEventList>(), //
        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<ReadApplicationLauncherEventList>(), //
        make_unique<SubscribeAttributeApplicationLauncherEventList>(), //
        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<ReadApplicationBasicEventList>(), //
        make_unique<SubscribeAttributeApplicationBasicEventList>(), //
        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<ReadAccountLoginEventList>(), //
        make_unique<SubscribeAttributeAccountLoginEventList>(), //
        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<ReadElectricalMeasurementEventList>(), //
        make_unique<SubscribeAttributeElectricalMeasurementEventList>(), //
        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<ReadUnitTestingEventList>(), //
        make_unique<SubscribeAttributeUnitTestingEventList>(), //
        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);
    registerClusterAirQuality(commands);
    registerClusterSmokeCoAlarm(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);
}
