Matter: How to add custom attributes and commands into the standard cluster (ex: occupancy cluster server)

Dear Team,

I would like to know if it is possible to add custom attributes and commands to standard clusters, such as the Occupancy cluster. I have reviewed the "Adding a Custom Cluster" guide provided by Nordic, but I am unsure how to proceed with modifying standard clusters.

Could you please advise if this is feasible and, if so, provide some guidance on how to implement it?

Best regards,
Bhavya

Parents
  • Hi Bhavya, 

    I will investigate if it is allowed by the Matter specification to add attributes/commands which are not included in the cluster definition. I suggest that you also check this if you are able to. 

    I assume you are using the latest nRF Connect SDK release (v3.0.2)? This is important to refer to the correct version of the Matter specification(s). If you are using nRF Connect SDK, the Matter v1.4 specification is the correct version. 

    Best regards,

    Maria

  • Hi  ,

    As per your suggested way I am able to add the custom coammand in standard cluster but facing issue in compiling the example.

    I have generated extended XML as per below for RoomSizeCfg command.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configurator>
      <clusterExtension code="0x0406"> <!-- Use lowercase or padded hex properly -->
        <command name="RoomSizeCfg" code="0xFFF10000" source="client" response="" optional="false" disableDefaultResponse="false">
          <description>Configure rangeSelCfg</description>
          <arg name="minMeters" type="single"/>
          <arg name="maxMeters" type="single"/>
        </command>
      </clusterExtension>
    </configurator>

    I can add this extended cluster file in zcl.json using the below command

    west zap-gui -j ./zcl.json --clusters ./extended.xml

    After that, I have generated the cluster code using below command successfully

    west zap-generate --full

    I have added the callback function in zcl_callbacks.cpp file (also added entry in CMakefile)

    #include <app/CommandHandler.h>
    #include <app/util/af-types.h>
    #include <app-common/zap-generated/callback.h>
    #include <app-common/zap-generated/cluster-objects.h>
    #include <app/ConcreteCommandPath.h>
    #include <app/InteractionModelEngine.h>
     
    using namespace chip;
    using namespace chip::app;
    using namespace chip::app::Clusters;
     
    bool emberAfOccupancySensingClusterRoomSizeCfgCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::OccupancySensing::Commands::RoomSizeCfg::
    DecodableType &commandData)
    {
    float min = commandData.minMeters;
    float max = commandData.maxMeters;
     
    return true;
    }

    I am getting this compilation error. Can you please check if anything is missing?

     *  Executing task: nRF Connect: Build: occupancy/build (active) 
    
    Building occupancy
    west build --build-dir /home/rahul/mangoe/occupancy/build /home/rahul/mangoe/occupancy
    
    [0/12] Performing build step for 'mcuboot'
    ninja: no work to do.
    [0/9] Performing build step for 'chip-gn'
    Starting Matter library build in /home/rahul/mangoe/occupancy/build/occupancy/modules/connectedhomeip
    Generating compile_commands took 64ms
    Done. Made 4248 targets from 307 files in 244ms
    ninja: no work to do.
    Matter library build complete
    [2/7] Linking CXX executable zephyr/zephyr_pre0.elf
    FAILED: zephyr/zephyr_pre0.elf zephyr/zephyr_pre0.map /home/rahul/mangoe/occupancy/build/occupancy/zephyr/zephyr_pre0.map 
    : && ccache /home/rahul/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-g++  -gdwarf-4 -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=free -Wl,--wrap=_malloc_r -Wl,--wrap=_calloc_r -Wl,--wrap=_realloc_r -Wl,--wrap=_free_r -Wl,-u,_ZN4chip5Shell6Engine11RunMainLoopEv zephyr/CMakeFiles/zephyr_pre0.dir/misc/empty_file.c.obj -o zephyr/zephyr_pre0.elf  zephyr/CMakeFiles/offsets.dir/./arch/arm/core/offsets/offsets.c.obj  -T  zephyr/linker_zephyr_pre0.cmd  -Wl,-Map=/home/rahul/mangoe/occupancy/build/occupancy/zephyr/zephyr_pre0.map  -Wl,--whole-archive  app/libapp.a  zephyr/libzephyr.a  zephyr/arch/common/libarch__common.a  zephyr/arch/arch/arm/core/libarch__arm__core.a  zephyr/arch/arch/arm/core/cortex_m/libarch__arm__core__cortex_m.a  zephyr/arch/arch/arm/core/cortex_m/cmse/libarch__arm__core__cortex_m__cmse.a  zephyr/arch/arch/arm/core/mpu/libarch__arm__core__mpu.a  zephyr/lib/libc/newlib/liblib__libc__newlib.a  zephyr/lib/libc/common/liblib__libc__common.a  zephyr/lib/posix/options/liblib__posix__options.a  zephyr/lib/net_buf/liblib__net_buf.a  zephyr/lib/os/zvfs/liblib__os__zvfs.a  zephyr/soc/soc/nrf54l15/libsoc__nordic.a  zephyr/subsys/random/libsubsys__random.a  zephyr/subsys/bluetooth/common/libsubsys__bluetooth__common.a  zephyr/subsys/bluetooth/host/libsubsys__bluetooth__host.a  zephyr/subsys/dfu/boot/libsubsys__dfu__boot.a  zephyr/subsys/net/libsubsys__net.a  zephyr/subsys/net/l2/openthread/libsubsys__net__ip__l2__openthread.a  zephyr/subsys/net/ip/libsubsys__net__ip.a  zephyr/drivers/cache/libdrivers__cache.a  zephyr/drivers/clock_control/libdrivers__clock_control.a  zephyr/drivers/console/libdrivers__console.a  zephyr/drivers/entropy/libdrivers__entropy.a  zephyr/drivers/flash/libdrivers__flash.a  zephyr/drivers/gpio/libdrivers__gpio.a  zephyr/drivers/hwinfo/libdrivers__hwinfo.a  zephyr/drivers/ieee802154/libdrivers__ieee802154.a  zephyr/drivers/pinctrl/libdrivers__pinctrl.a  zephyr/drivers/serial/libdrivers__serial.a  zephyr/drivers/spi/libdrivers__spi.a  zephyr/drivers/timer/libdrivers__timer.a  modules/nrf/lib/dk_buttons_and_leds/lib..__nrf__lib__dk_buttons_and_leds.a  modules/nrf/lib/multithreading_lock/lib..__nrf__lib__multithreading_lock.a  modules/nrf/lib/hw_unique_key/lib..__nrf__lib__hw_unique_key.a  modules/nrf/subsys/bluetooth/controller/lib..__nrf__subsys__bluetooth__controller.a  modules/nrf/subsys/nrf_security/src/zephyr/libmbedtls_zephyr.a  modules/nrf/subsys/dfu/dfu_multi_image/lib..__nrf__subsys__dfu__dfu_multi_image.a  modules/nrf/subsys/dfu/dfu_target/lib..__nrf__subsys__dfu__dfu_target.a  modules/nrf/subsys/mpsl/init/lib..__nrf__subsys__mpsl__init.a  modules/nrf/subsys/mpsl/fem/lib..__nrf__subsys__mpsl__fem.a  modules/nrf/subsys/ieee802154/lib..__nrf__subsys__ieee802154.a  modules/nrf/drivers/mpsl/clock_control/lib..__nrf__drivers__mpsl__clock_control.a  modules/nrf/drivers/mpsl/flash_sync/lib..__nrf__drivers__mpsl__flash_sync.a  modules/nrf/drivers/mpsl/temp_nrf5/lib..__nrf__drivers__mpsl__temp_nrf5.a  modules/mcuboot/boot/bootutil/zephyr/libmcuboot_util.a  modules/openthread/platform/libopenthread_platform.a  modules/hal_nordic/modules/hal_nordic/nrf_802154/libnrf-802154-platform.a  modules/nrfxlib/nrf_802154/nrf_802154/driver/libnrf-802154-driver.a  modules/hal_nordic/modules/hal_nordic/nrfx/libmodules__hal_nordic__nrfx.a  modules/zcbor/libmodules__zcbor.a  /home/rahul/ncs/v3.0.1/nrfxlib/openthread/lib/nrf54lx/soft-float/v1.4/mtd/libopenthread-mtd.a  -Wl,--no-whole-archive  zephyr/kernel/libkernel.a  -L/home/rahul/mangoe/occupancy/build/occupancy/zephyr  -Wl,--start-group  modules/connectedhomeip/lib/libCHIP.a  modules/connectedhomeip/lib/libMatterDeviceInfoProviderExample.a  -Wl,--end-group  zephyr/arch/common/libisr_tables.a  modules/nrfxlib/nrf_802154/nrf_802154/common/libnrf-802154-common.a  modules/hal_nordic/modules/hal_nordic/nrf_802154/libnrf-802154-platform.a  /home/rahul/ncs/v3.0.1/nrfxlib/nrf_802154/sl/sl/lib/nrf54l15_cpuapp/soft-float/libnrf-802154-sl.a  -mcpu=cortex-m33  -mthumb  -mabi=aapcs  -mfp16-format=ieee  -fuse-ld=bfd  -Wl,--gc-sections  -Wl,--build-id=none  -Wl,--sort-common=descending  -Wl,--sort-section=alignment  -Wl,-u,_OffsetAbsSyms  -Wl,-u,_ConfigAbsSyms  -nostdlib  -static  -Wl,-X  -Wl,-N  -Wl,--orphan-handling=warn  -Wl,-no-pie  -L"/home/rahul/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk/arm-zephyr-eabi/arm-zephyr-eabi"/lib/thumb/v8-m.main/nofp  -u_printf_float  -specs=nano.specs  modules/nrf/subsys/nrf_security/src/libmbedcrypto.a  modules/nrf/subsys/nrf_security/src/core/nrf_oberon/liboberon_psa_core.a  modules/nrf/subsys/nrf_security/src/drivers/cracen/libcracen_psa_driver.a  modules/nrf/subsys/nrf_security/src/libmbedcrypto_base.a  modules/nrf/subsys/nrf_security/src/libnrf_security_utils.a  zephyr/kernel/libkernel.a  -lc  /home/rahul/ncs/v3.0.1/nrfxlib/softdevice_controller/lib/nrf54l/soft-float/libsoftdevice_controller_multirole.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/fem/common/lib/nrf54l/soft-float/libmpsl_fem_common.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/fem/nrf21540_gpio/lib/nrf54l/soft-float/libmpsl_fem_nrf21540_gpio.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/fem/nrf21540_gpio_spi/lib/nrf54l/soft-float/libmpsl_fem_nrf21540_gpio_spi.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/fem/nrf2220/lib/nrf54l/soft-float/libmpsl_fem_nrf2220.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/fem/nrf2240/lib/nrf54l/soft-float/libmpsl_fem_nrf2240.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/fem/nrf22xx/lib/nrf54l/soft-float/libmpsl_fem_nrf22xx.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/fem/simple_gpio/lib/nrf54l/soft-float/libmpsl_fem_simple_gpio.a  /home/rahul/ncs/v3.0.1/nrfxlib/mpsl/lib/nrf54l/soft-float/libmpsl.a -L"/home/rahul/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/thumb/v8-m.main/nofp" -lstdc++ -lm -lc -lgcc -lc && cd /home/rahul/mangoe/occupancy/build/occupancy/zephyr && /home/rahul/ncs/toolchains/7cbc0036f4/usr/local/bin/cmake -E true
    /home/rahul/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: app/libapp.a(IMClusterCommandHandler.cpp.obj): in function `chip::ChipError chip::app::DataModel::Decode<chip::app::Clusters::OccupancySensing::Commands::RoomSizeCfg::DecodableType, (chip::app::Clusters::OccupancySensing::Commands::RoomSizeCfg::DecodableType*)0>(chip::TLV::TLVReader&, chip::app::Clusters::OccupancySensing::Commands::RoomSizeCfg::DecodableType&)':
    /home/rahul/ncs/v3.0.1/modules/lib/matter/src/app/data-model/Decode.h:114: undefined reference to `chip::app::Clusters::OccupancySensing::Commands::RoomSizeCfg::DecodableType::Decode(chip::TLV::TLVReader&)'
    collect2: error: ld returned 1 exit status
    ninja: build stopped: subcommand failed.
    [4/12] cd /home/rahul/mangoe/occupancy/build/_sysbuild && /home/rahul/ncs/toolchains/7cbc0036f4/usr/local/bin/cmake -E true
    FAILED: _sysbuild/sysbuild/images/occupancy-prefix/src/occupancy-stamp/occupancy-build /home/rahul/mangoe/occupancy/build/_sysbuild/sysbuild/images/occupancy-prefix/src/occupancy-stamp/occupancy-build 
    cd /home/rahul/mangoe/occupancy/build/occupancy && /home/rahul/ncs/toolchains/7cbc0036f4/usr/local/bin/cmake --build .
    ninja: build stopped: subcommand failed.
    FATAL ERROR: command exited with status 1: /home/rahul/ncs/toolchains/7cbc0036f4/usr/local/bin/cmake --build /home/rahul/mangoe/occupancy/build
    
     *  The terminal process terminated with exit code: 1. 
     *  Terminal will be reused by tasks, press any key to close it. 
    

    Thank you,

    Bhavya

  • Hi Bhavya, 

    Does the build also fail when you build pristinely? 

    Best regards,

    Maria

  • Hi  ,

    Yes, I have also done a pristine build. But it seems like after adding the below code snippet in the CMakefile, I can compile.

    # Override zap-generated directory.
    get_filename_component(CHIP_APP_ZAP_DIR ${CONFIG_NCS_SAMPLE_MATTER_ZAP_FILES_PATH}/zap-generated REALPATH CACHE)
    message(STATUS "CHIP_APP_ZAP_DIR: ${CHIP_APP_ZAP_DIR}")

    Thank you,

    Bhavya

  • Hi Maria,

    I’ve successfully added a custom command to the existing Occupancy (0x0406) cluster, and it works fine. Now, I want to add a struct attribute and a simple standalone attribute in the same cluster.

    I am using the following command to load my extended XML:

    west zap-gui -j ./zcl.json --clusters ./new.xml
    

    But the new attributes are not appearing in ZAP-GUI. I believe I might be missing something in the XML definition.

    Could you please guide me on the correct way to define structs and attributes in XML so they show up properly in ZAP-GUI?

    Thanks,
    Rahul chauhan.

  • Hi  ,

    We are able to add custom commands in the standard cluster and also able to add attribute with the simple data type like int8, uint8 but we are facing issue in adding attributes with the structure data type. One more thing I would like to inform you that, the tool "nrf connect Matter manufacturer cluster editor" is not able to generate XML code for the structures so we have put the structure code in xml file manually as below.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configurator>
    
      <struct apiMaturity="stable" name="RoomSizeCfgStruct">
        <cluster code="0x0406"/> <!-- Occupancy Sensing Cluster -->
        <item name="minMeters" fieldId="1" type="int16u" optional="false"/>
        <item name="maxMeters" fieldId="2" type="int16u" optional="false"/>    
      </struct>
    
      <clusterExtension code="0x406">
        <attribute side="server" code="0xfff11004" define="ZONE_OCCUPANCY" type="int16u" writable="true" optional="false" default="0" name="ZoneOccupancy">
          <description>ZoneOccupancy</description>
        </attribute>
        <attribute name="RoomSize" side="server" code="0xfff11000" define="ROOM_SIZE" type="RoomSizeCfgStruct" writable="false" optional="false" storage="external">
          <description>RoomSize</description>      
        </attribute>
        <command name="RoomSizeCfg" code="0xfff10000" source="client" response="CfgCmdResponse" optional="false" disableDefaultResponse="false">
          <description>Configure rangeSelCfg</description>
          <arg name="minMeters" type="single"/>
          <arg name="maxMeters" type="single"/>
        </command>
      </clusterExtension>
    </configurator>
    
    

    we have selected storage as RAM

    initially we are facing issue in generating code using zap-generate --full. We have added in attribute name manually in zcl.json file at attributeAccessInterfaceAttributes as below.

    I am able to generate files and build it but not able to read the attribute value throgh chip tool. Can you please try to replicate the attribute addition with struct type and check the behavior if we are missing something.

    Thank you,

    Bhavya 

Reply
  • Hi  ,

    We are able to add custom commands in the standard cluster and also able to add attribute with the simple data type like int8, uint8 but we are facing issue in adding attributes with the structure data type. One more thing I would like to inform you that, the tool "nrf connect Matter manufacturer cluster editor" is not able to generate XML code for the structures so we have put the structure code in xml file manually as below.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configurator>
    
      <struct apiMaturity="stable" name="RoomSizeCfgStruct">
        <cluster code="0x0406"/> <!-- Occupancy Sensing Cluster -->
        <item name="minMeters" fieldId="1" type="int16u" optional="false"/>
        <item name="maxMeters" fieldId="2" type="int16u" optional="false"/>    
      </struct>
    
      <clusterExtension code="0x406">
        <attribute side="server" code="0xfff11004" define="ZONE_OCCUPANCY" type="int16u" writable="true" optional="false" default="0" name="ZoneOccupancy">
          <description>ZoneOccupancy</description>
        </attribute>
        <attribute name="RoomSize" side="server" code="0xfff11000" define="ROOM_SIZE" type="RoomSizeCfgStruct" writable="false" optional="false" storage="external">
          <description>RoomSize</description>      
        </attribute>
        <command name="RoomSizeCfg" code="0xfff10000" source="client" response="CfgCmdResponse" optional="false" disableDefaultResponse="false">
          <description>Configure rangeSelCfg</description>
          <arg name="minMeters" type="single"/>
          <arg name="maxMeters" type="single"/>
        </command>
      </clusterExtension>
    </configurator>
    
    

    we have selected storage as RAM

    initially we are facing issue in generating code using zap-generate --full. We have added in attribute name manually in zcl.json file at attributeAccessInterfaceAttributes as below.

    I am able to generate files and build it but not able to read the attribute value throgh chip tool. Can you please try to replicate the attribute addition with struct type and check the behavior if we are missing something.

    Thank you,

    Bhavya 

Children
  • Hi,

    I saw you created a new ticket here:  Support Needed for Adding Custom Attribute of Struct data type in standard cluster .

    Do you wish to continue in the new ticket or this one?

    I have replied in the other ticket already, so I will copy my response here:

    Can you try changing the type to array and adding RoomSizeCfgStruct as entryType instead? Like this:

    <attribute name="RoomSize" side="server" code="0xfff11000" define="ROOM_SIZE" type="array" entryType="RoomSizeCfgStruct" writable="false" optional="false" storage="external">

    Here is the full XML with this change:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configurator>
      <struct apiMaturity="stable" name="RoomSizeCfgStruct">
        <cluster code="0x0406"/> <!-- Occupancy Sensing Cluster -->
        <item name="minMeters" fieldId="1" type="int16u" optional="false"/>
        <item name="maxMeters" fieldId="2" type="int16u" optional="false"/>    
      </struct>
      <clusterExtension code="0x0406">
        <attribute side="server" code="0xfff11004" define="ZONE_OCCUPANCY" type="int16u" writable="true" optional="false" default="0" name="ZoneOccupancy">
          <description>ZoneOccupancy</description>
        </attribute>
        <attribute name="RoomSize" side="server" code="0xfff11000" define="ROOM_SIZE" type="array" entryType="RoomSizeCfgStruct" writable="false" optional="false" storage="external">
          <description>RoomSize</description>      
        </attribute>
      </clusterExtension>
    </configurator>

    Best regards,
    Marte 

  • Hi  ,

    We can continue in the new ticket.

    You can close this ticket.

    Thank you,

    Bhavya

Related