# Writing and Updating Clusters

This guide provides a comprehensive walkthrough for creating a new Matter
cluster implementation, referred to as a "code-driven" cluster.

## Overview of the Process

Writing a new cluster involves the following key stages:

1. **Define the Cluster:** Generate or update the cluster definition XML based
   on the Matter specification.
2. **Implement the Cluster:** Write the C++ implementation for the cluster's
   logic and data management.
3. **Integrate with Build System:** Add the necessary files to integrate the new
   cluster into the build process.
4. **Integrate with Application:** Connect the cluster to an application's code
   generation configuration.
5. **Test:** Add unit and integration tests to verify the cluster's
   functionality.

---

## Part 1: Cluster Definition (XML)

Clusters are defined based on the Matter specification. The C++ code for them is
generated from XML definitions located in
`src/app/zap-templates/zcl/data-model/chip`.

-   **Generate XML:** To create or update a cluster XML, use
    [Alchemy](https://github.com/project-chip/alchemy) to parse the
    specification's `asciidoc`. Manual editing of XML is discouraged, as it is
    error-prone.
-   **Run Code Generation:** Once the XML is ready, run the code generation
    script. It's often sufficient to run:

    ```bash
    ./scripts/run_in_build_env.sh 'scripts/tools/zap_regen_all.py'
    ```

    For more details, see the
    [code generation guide](../zap_and_codegen/code_generation.md).

---

## Part 2: C++ Implementation

### File Structure

Create a new directory for your cluster at
`src/app/clusters/<cluster-directory>/`. This directory will house the cluster
implementation and its unit tests.

For zap-based support, the directory mapping is defined in
[src/app/zap_cluster_list.json](https://github.com/project-chip/connectedhomeip/blob/master/src/app/zap_cluster_list.json)
under the `ServerDirectories` key. This maps the `UPPER_SNAKE_CASE` define of
the cluster to the directory name under `src/app/clusters`.

#### Naming conventions

Names vary, however to be consistent with most of the existing code use:

-   `cluster-name-server` for the cluster directory name
-   `ClusterNameSnakeCluster.h/cpp` for the `ServerClusterInterface`
    implementation

### Recommended Implementation Pattern

For optimal flash and RAM usage on resource-constrained devices, we strongly
recommend a **combined implementation** pattern. You should avoid splitting the
implementation into separate logic and translation layers, as this introduces
unnecessary overhead.

-   **Combined Implementation (Recommended):**

    -   The cluster's logic, data storage, and `ServerClusterInterface`
        implementation are all contained within a single class (often by
        deriving from `DefaultServerCluster`).
    -   This minimizes boilerplate and virtual function translation layers,
        resulting in a significantly smaller flash footprint.
    -   **Example:** The
        [Basic Information](https://github.com/project-chip/connectedhomeip/tree/master/src/app/clusters/basic-information)
        cluster is a good example of a combined implementation.

-   **Modular Implementation / `ClusterLogic` (Not Recommended):**

    -   Historically, some clusters separated core business logic into a
        type-safe `ClusterLogic` class, with a `ClusterImplementation` class
        acting as a translation layer.
    -   While this isolated the logic for testing, it adds noticeable flash and
        RAM overhead and is **discouraged** for new clusters.
    -   **Example:** The
        [Administrator Commissioning](https://github.com/project-chip/connectedhomeip/tree/master/src/app/clusters/administrator-commissioning-server)
        cluster demonstrates this legacy modular implementation.

-   **`ClusterDriver` (or `Delegate`):**
    -   An optional interface providing callbacks to the application for cluster
        interactions. We recommend the term `Driver` to avoid confusion with the
        overloaded term `Delegate`.

### Design Principles

When designing and implementing a cluster, adhere to the following principles to
ensure a high-quality and developer-friendly experience:

#### Prioritize Easy Application Development

Clusters should aim to do as much work as possible autonomously, reducing the
burden on the application developer.

-   **Handle Common Logic Internally:** Implement persistence (NVM), timers, and
    complex state machines within the cluster itself. The application should
    only be notified of significant events or changes it needs to act upon. _For
    example, a state machine managing a multi-step process like a firmware
    update, door lock/unlock sequence with retries, or a calibration procedure
    should typically reside within the cluster, rather than requiring the
    application to manage the intermediate steps and timeouts._
-   **Provide Helper Abstractions:** If a cluster requires the application to
    implement complex logic, consider providing helper classes or default
    implementations that simplify the task.
-   **Encapsulate Complexity:** Avoid deferring low-level details (like raw
    storage keys or individual timer management) to the application.

#### Delegate/Driver Pattern for Validation

When an application needs to be involved in a cluster operation (especially
writes or commands), use a delegate (or driver) interface that acts as a
"pre-check."

-   **Pre-Write Validation:** For writable attributes, provide a callback that
    allows the application to accept or reject the new value _before_ it is
    applied to the cluster's internal state or persisted.
-   **Delegate Veto:** Callbacks must return a
    `Protocols::InteractionModel::Status`. Returning any status other than
    Success allows the application to reject the proposed change. The cluster
    MUST honor this by failing the operation and propagating the delegate's
    status code to the initiator.
-   **Perform Cluster-Level Checks First:** The cluster remains responsible for
    all spec-defined validations (e.g., range checks, constraint validations, or
    state-based restrictions) before involving the application delegate.
-   **Avoid Redundant Notifications:** Ensure that no-op operations (e.g.,
    writing the same value that is already present) are handled early and do not
    trigger delegate callbacks or change notifications.

### BUILD file layout

The description below will describe build files under
`src/app/clusters/<cluster-directory>/`. You are expected to have the following
items:

#### `BUILD.gn`

This file will contain a target that is named `<cluster-directory>`, usually a
`source_set`. This file gets referenced from
[src/app/chip_data_model.gni](https://github.com/project-chip/connectedhomeip/blob/master/src/app/chip_data_model.gni)
by adding a dependency as `deps += [ "${_app_root}/clusters/${cluster}" ]`, so
the default target name is important.

#### `app_config_dependent_sources`

There are two code generation integration support files: one for `GN` and one
for `CMake`. The way these work is that
`chip_data_model.gni`/`chip_data_model.cmake` will include these files and
bundle _ALL_ referenced sources into _ONE SINGLE SOURCE SET_, together with
ember code-generated settings (e.g. `endpoint_config.h` and similar files that
are application-specific)

As a result, there will be a difference between `.gni` and `.cmake`:

-   `app_config_dependent_sources.gni` will typically just contain
    `CodegenIntegration.cpp` and any other helper/compatibility layers (e.g.
    `CodegenIntegration.h` if applicable)
-   `app_config_dependent_sources.cmake` will contain all the files that the
    `.gni` file contains PLUS any dependencies that the `BUILD.gn` would pull in
    but cmake would not (i.e. dependencies not in the `libCHIP` builds). These
    extra files are often the `*.h/*.cpp` files that were in the `BUILD.gn`
    source set.

**EXAMPLE** taken from
([src/app/clusters/basic-information](https://github.com/project-chip/connectedhomeip/tree/master/src/app/clusters/basic-information)):

```
# BUILD.gn
import("//build_overrides/build.gni")
import("//build_overrides/chip.gni")

source_set("basic-information") {
   sources = [ ... ]
   public_deps = [ ... ]
}
```

```
# app_config_dependent_sources.gni
app_config_dependent_sources = [ "CodegenIntegration.cpp" ]
```

```
# app_config_dependent_sources.cmake
# This block adds the codegen integration sources, similar to app_config_dependent_sources.gni
TARGET_SOURCES(
  ${APP_TARGET}
  PRIVATE
    "${CLUSTER_DIR}/CodegenIntegration.cpp"
)

# These are the things that BUILD.gn dependencies would pull
TARGET_SOURCES(
  ${APP_TARGET}
  PRIVATE
    "${CLUSTER_DIR}/BasicInformationCluster.cpp"
    "${CLUSTER_DIR}/BasicInformationCluster.h"
)
```

### Implementation Details

#### Attribute and Feature Handling

Your implementation must correctly report which attributes and commands are
available based on the enabled features and optional items.

-   Use a feature map to control elements dependent on features.
-   Use boolean flags or `BitFlags` for purely optional elements.
-   Ensure your unit tests cover different combinations of enabled features and
    optional attributes/commands.

#### Attribute Accessors

Your cluster implementation must provide public getter and setter APIs for each
attribute to allow applications to interact with cluster state.

-   **Getter Methods:** Provide a getter method for every attribute (e.g.,
    `GetCurrentSensitivityLevel()`, `GetAlarmsActive()`). Applications need
    these to read the current cluster state.

    -   **Return by value (preferred):** Getters should return copies of data
        whenever practical. This avoids lifetime and ownership concerns.

    -   **Avoid returning pointers or references:** Returning pointers or
        references to internal cluster data create lifetime risks—if the
        underlying memory is deallocated while the caller still holds the
        pointer, use-after-free bugs can occur. If you must return a pointer or
        reference, clearly document that the returned value is only valid for
        immediate use and must not be stored.

-   **Setter Methods:** Provide methods to modify all non-fixed (mutable)
    attributes in spec-compliant ways. For simple attributes, this may be a
    straightforward setter (e.g., `SetCurrentSensitivityLevel()`). However, spec
    compliance may require updating multiple attributes together atomically—in
    such cases, provide a higher-level API that encapsulates the required
    behavior rather than individual setters. When the application's driver state
    changes, these methods can be used to update the cluster's state
    accordingly. Setters are also responsible for triggering attribute change
    notifications (see
    [Attribute Change Notifications](#attribute-change-notifications)).

-   **Example:** The
    [Boolean State Configuration](https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/boolean-state-configuration-server/BooleanStateConfigurationCluster.h)
    cluster demonstrates this pattern.

#### Attribute Change Notifications

For subscriptions to work correctly, you must notify the system whenever an
attribute's value changes.

-   The `Startup` method of your cluster receives a `ServerClusterContext`.
-   Use the context to call
    `interactionContext->dataModelChangeListener->MarkDirty(path)`. A
    `NotifyAttributeChanged` helper exists for paths managed by this cluster.

    -   For write implementations, you can use `NotifyAttributeChangedIfSuccess`
        together with a separate `WriteImpl` such that any successful attribute
        write will notify.

        Canonical example code would look like:

        ```cpp
        DataModel::ActionReturnStatus SomeCluster::WriteAttribute(const DataModel::WriteAttributeRequest & request,
                                                                          AttributeValueDecoder & decoder)
        {
                // Delegate everything to WriteImpl. If write succeeds, notify that the attribute changed.
                return NotifyAttributeChangedIfSuccess(request.path.mAttributeId, WriteImpl(request, decoder));
        }
        ```

    -   For the `NotifyAttributeChangedIfSuccess` ensure that WriteImpl is
        returning
        [ActionReturnStatus::FixedStatus::kWriteSuccessNoOp](https://github.com/project-chip/connectedhomeip/blob/master/src/app/data-model-provider/ActionReturnStatus.h)
        when no notification should be sent.

        **Crucial:** No-op writes (where the value remains unchanged) MUST NOT
        trigger:

        -   Network attribute change notifications.
        -   Application-level delegate/driver callbacks.

        Canonical example is:

        ```cpp
        VerifyOrReturnValue(mValue != newValue, ActionReturnStatus::FixedStatus::kWriteSuccessNoOp);
        ```

-   **Per-Attribute Change Callbacks:** As a concrete realization of the
    [Delegate/Driver Pattern for Validation](#delegate-driver-pattern-for-validation),
    each mutable attribute should have a corresponding
    `On<AttributeName>Changed` callback in the delegate interface. These are
    _pre-write_ hooks invoked after spec-level validation and the no-op guard,
    but _before_ the value is committed. The callback must always receive the
    **proposed new value**, not the current (stale) value. Returning `true`
    accepts the change; returning `false` vetoes it. The cluster must then fail
    the operation with `Protocols::InteractionModel::Status::Failure` (for APIs
    returning `Status`) or `CHIP_ERROR_INCORRECT_STATE` (for APIs returning
    `CHIP_ERROR`). Default implementations should return `true` so applications
    only override the callbacks they need.

    **Example:** The
    [Boolean State Configuration delegate](https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/boolean-state-configuration-server/boolean-state-configuration-delegate.h)
    declares:

    ```cpp
    virtual bool OnCurrentSensitivityLevelChanged(uint8_t newValue) { return true; }
    virtual bool OnAlarmsActiveChanged(chip::BitMask<AlarmModeBitmap> newValue) { return true; }
    virtual bool OnAlarmsSuppressedChanged(chip::BitMask<AlarmModeBitmap> newValue) { return true; }
    virtual bool OnAlarmsEnabledChanged(chip::BitMask<AlarmModeBitmap> newValue) { return true; }
    virtual bool OnSensorFaultChanged(chip::BitMask<SensorFaultBitmap> newValue) { return true; }
    ```

    And the cluster invokes them in the standard order—validate, guard no-op,
    call delegate, then commit and notify:

    ```cpp
    VerifyOrReturnError(level < mSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(ConstraintError));
    VerifyOrReturnError(mCurrentSensitivityLevel != level, CHIP_NO_ERROR);

    if (mDelegate != nullptr)
    {
        VerifyOrReturnError(mDelegate->OnCurrentSensitivityLevelChanged(level), CHIP_ERROR_INCORRECT_STATE);
    }

    mCurrentSensitivityLevel = level;
    NotifyAttributeChanged(CurrentSensitivityLevel::Id);
    ```

#### Persistent Storage

-   **Attributes:** For scalar attribute values, use `AttributePersistence` from
    `src/app/persistence/AttributePersistence.h`. The `ServerClusterContext`
    provides an `AttributePersistenceProvider`.
-   **General Storage:** For non-attribute data, the context provides a
    `PersistentStorageDelegate`.

#### Optimizing for Flash/RAM

For common or large clusters, you may need to optimize for resource usage.
Consider using `C++` templates to compile-time select features and attributes,
which can significantly reduce flash and RAM footprint.

### Advanced `ServerClusterInterface` Details

While `ReadAttribute`, `WriteAttribute`, and `InvokeCommand` are the most
commonly implemented methods, the `ServerClusterInterface` has other methods for
more advanced use cases.

#### List Attribute Writes (`ListAttributeWriteNotification`)

This method is an advanced callback for handling large list attributes that may
require special handling, such as persisting them to storage in chunks. A
typical example of a cluster that might use this is the **Binding cluster**. For
most clusters, the default implementation is sufficient.

#### Event Permissions (`EventInfo`)

You must implement the `EventInfo` method if your cluster emits any events that
require non-default permissions to be read. For example, an event might require
`Administrator` privileges. While not common, this should be verified for every
new cluster implementation and checked during code reviews to ensure event
access is correctly restricted.

#### Accepted vs. Generated Commands

The distinction between `AcceptedCommands` and `GeneratedCommands` can be
understood using a REST API analogy:

-   **`AcceptedCommands`**: These are the "requests" that the server cluster can
    process. In the Matter specification, these are commands sent from the
    client to the server (`client => server`).
-   **`GeneratedCommands`**: These are the "responses" that the server cluster
    can generate after processing an accepted command. In the spec, these are
    commands sent from the server back to the client (`server => client`).

These lists are built based on the cluster's definition in the Matter
specification.

### Unit Testing

Unit tests should reside in `src/app/clusters/<cluster-name>/tests/`.

Use the `chip::Testing::ClusterTester` utility to write your unit tests. This
modern API removes the need to manually mock encoders, handlers, or raw TLV
buffers. More on [ClusterTester Helper Class Guide](cluster_tester.md).

-   **Test Setup:** Create a mock delegate to inject fake data into your cluster
    instance.
-   **Menu Verification:** Ensure `Attributes()` and `AcceptedCommands()` return
    the correct metadata, or `ClusterTester` will reject your reads/invocations.
-   **Reads:** Test `ReadAttribute` via `tester.ReadAttribute()` and verify data
    matches your mock.
-   **Commands:** Test commands via `tester.Invoke()` and ensure specific
    `Protocols::InteractionModel::Status` codes are returned accurately based on
    delegate responses.
-   **Reporting:** Verify reporting logic by reading `tester.GetDirtyList()` to
    ensure state changes properly mark attributes as dirty, while No-Op writes
    do not.

---

## Part 3: Build and Application Integration

### Build System Integration

The build system maps cluster names to their source directories. Add your new
cluster to this mapping:

-   Edit `src/app/zap_cluster_list.json` and add an entry for your cluster,
    pointing to the directory you created.

### Application Integration (`CodegenIntegration.cpp`)

To integrate your cluster with an application's `.zap` file configuration, you
need to bridge the gap between the statically generated code and your C++
implementation.

1. **Create `CodegenIntegration.cpp`:** This file will contain the integration
   logic.
2. **Create Build Files:** Add `app_config_dependent_sources.gni` and
   `app_config_dependent_sources.cmake` to your cluster directory. These files
   should list `CodegenIntegration.cpp` and its dependencies. See existing
   clusters for examples.
3. **Use Generated Configuration:** The code generator creates a header file at
   `<app/static-cluster-config/<cluster-name>.h` that provides static,
   application-specific configuration. Use this to initialize your cluster
   correctly for each endpoint.
4. **Implement Callbacks:** Implement
   `Matter<Cluster>ClusterInitCallback(EndpointId)` and
   `Matter<Cluster>ClusterShutdownCallback(EndpointId)` in your
   `CodegenIntegration.cpp`.
5. **Update `config-data.yaml`:** To enable these callbacks, add your cluster to
   the `CodeDrivenClusters` array in
   `src/app/common/templates/config-data.yaml`.
6. **Update ZAP Configuration:** To prevent the Ember framework from allocating
   memory for your cluster's attributes, you must:
    - In `src/app/zap-templates/zcl/zcl.json` and
      `zcl-with-test-extensions.json`, add all non-list attributes of your
      cluster to `attributeAccessInterfaceAttributes`. This marks them as
      externally handled.
7. **Regenerate ZAP:** Once `config-data.yaml` and
   `zcl.json/zcl-with-test-extensions.json` are updated, run the ZAP
   regeneration command, like

    ```bash
    ./scripts/run_in_build_env.sh 'scripts/tools/zap_regen_all.py'
    ```

---

## Part 4: Example Application and Integration Testing

-   Write unit tests to ensure cluster test coverage
-   **Integrate into an Example:** Add your cluster to an example application,
    such as the `all-clusters-app`, to test it in a real-world scenario.
    -   use tools such as `chip-tool` or `matter-repl` to manually validate the
        cluster
-   **Add Integration Tests:** Write integration tests to validate the
    end-to-end functionality of your cluster against the example application.
