diff --git a/.clang-tidy b/.clang-tidy index 580234c0fad0a3..5a6f103705fc39 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,7 @@ --- Checks: > bugprone-*, + modernize-redundant-void-arg, modernize-use-bool-literals, modernize-use-nullptr, performance-for-range-copy, diff --git a/.github/labeler.yml b/.github/labeler.yml index 5f7f83bf647407..235d671213f425 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -216,3 +216,7 @@ zephyr: telink: - src/platform/telink/* - src/platform/telink/**/* + +tizen: + - src/platform/Tizen/* + - src/platform/Tizen/**/* diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 276b1f264e0cee..4a3ce8550c2e7e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -229,12 +229,28 @@ jobs: run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --no-log-timestamps \ - --target linux-x64-all-clusters-ipv6only-clang \ - --target linux-x64-chip-tool-ipv6only-clang \ --target linux-x64-minmdns-ipv6only-clang \ --target linux-x64-rpc-console \ build \ " + - name: Create a pre-generate directory and ensure compile-time codegen would fail + run: | + ./scripts/run_in_build_env.sh "./scripts/codepregen.py ./zzz_pregenerated" + mv scripts/codegen.py scripts/codegen.py.renamed + - name: Build using build_examples.py (pregen) + timeout-minutes: 60 + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py --no-log-timestamps \ + --target linux-x64-all-clusters-ipv6only-clang \ + --target linux-x64-chip-tool-ipv6only-clang \ + --pregen-dir ./zzz_pregenerated \ + build \ + " + - name: Undo code pre-generation changes (make compile time codegen work again) + run: | + rm -rf ./zzz_pregenerated + mv scripts/codegen.py.renamed scripts/codegen.py - name: Run fake linux tests with build_examples timeout-minutes: 15 run: | diff --git a/.github/workflows/darwin.yaml b/.github/workflows/darwin.yaml index 8c3b2231bcf17c..a3eda2ef715b0b 100644 --- a/.github/workflows/darwin.yaml +++ b/.github/workflows/darwin.yaml @@ -107,11 +107,11 @@ jobs: run: | scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug chip_config_network_layer_ble=false - name: Build example OTA Provider - timeout-minutes: 5 + timeout-minutes: 10 run: | scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/debug chip_config_network_layer_ble=false - name: Build example OTA Requestor - timeout-minutes: 5 + timeout-minutes: 10 run: | scripts/examples/gn_build_example.sh examples/ota-requestor-app/linux out/debug chip_config_network_layer_ble=false - name: Delete Defaults diff --git a/.github/workflows/docker_img.yaml b/.github/workflows/docker_img.yaml index bd3fb575b2957e..a0fc677dfc06d4 100644 --- a/.github/workflows/docker_img.yaml +++ b/.github/workflows/docker_img.yaml @@ -57,7 +57,6 @@ jobs: - "-openiotsdk" # NOTE: vscode image consumes ~52 GB disk space but GitHub-hosted runners provide ~10 GB free disk space(https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources) #- "-vscode" - - "-zap" steps: - uses: Wandalen/wretry.action@v1.0.36 name: Checkout diff --git a/.github/workflows/examples-bouffalolab.yaml b/.github/workflows/examples-bouffalolab.yaml index 9c31fbd9ba581e..8e137c4738b281 100644 --- a/.github/workflows/examples-bouffalolab.yaml +++ b/.github/workflows/examples-bouffalolab.yaml @@ -31,7 +31,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:latest + image: connectedhomeip/chip-build-bouffalolab:0.6.12 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -44,7 +44,7 @@ jobs: attempt_limit: 3 attempt_delay: 2000 - name: Checkout submodules - run: scripts/checkout_submodules.py --shallow --platform bl602 + run: scripts/checkout_submodules.py --shallow --platform bouffalolab --recursive - name: Set up environment for size reports if: ${{ !env.ACT }} @@ -87,7 +87,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:latest + image: connectedhomeip/chip-build-bouffalolab:0.6.12 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -100,7 +100,7 @@ jobs: attempt_limit: 3 attempt_delay: 2000 - name: Checkout submodules - run: scripts/checkout_submodules.py --shallow --platform bouffalolab + run: scripts/checkout_submodules.py --shallow --platform bouffalolab --recursive - name: Set up environment for size reports if: ${{ !env.ACT }} diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 62db94b48325af..d245cea56323f5 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -72,7 +72,7 @@ jobs: .environment/pigweed-venv/*.log - name: Build some BRD4187C variants - timeout-minutes: 50 + timeout-minutes: 90 run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py \ @@ -96,25 +96,33 @@ jobs: efr32 BRD4187C window-app \ out/efr32-brd4187c-window-covering/chip-efr32-window-example.out \ /tmp/bloat_reports/ + - name: Clean out build output + run: rm -rf ./out - name: Build example EFR32 Lighting App for BRD4161A with RPCs timeout-minutes: 15 run: | - scripts/examples/gn_efr32_example.sh examples/lighting-app/efr32/ out/lighting_app_debug_rpc BRD4161A "is_debug=false" \ + scripts/examples/gn_efr32_example.sh examples/lighting-app/silabs/efr32/ out/lighting_app_debug_rpc BRD4161A "is_debug=false" \ disable_lcd=true 'import("//with_pw_rpc.gni")' .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py efr32 BRD4161A+rpc lighting-app \ out/lighting_app_debug_rpc/BRD4161A/chip-efr32-lighting-example.out /tmp/bloat_reports/ + - name: Clean out build output + run: rm -rf ./out - name: Build example EFR32+WF200 WiFi Lock app for BRD4161A timeout-minutes: 15 run: | scripts/examples/gn_efr32_example.sh examples/lock-app/efr32/ out/lock_app_wifi_wf200 BRD4161A is_debug=false --wifi wf200 .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py efr32 BRD4161A+wf200 lock-app \ out/lock_app_wifi_wf200/BRD4161A/chip-efr32-lock-example.out /tmp/bloat_reports/ + - name: Clean out build output + run: rm -rf ./out - name: Build example EFR32+RS911x WiFi Lighting app for BRD4161A timeout-minutes: 15 run: | - scripts/examples/gn_efr32_example.sh examples/lighting-app/efr32/ out/lighting_app_wifi_rs911x BRD4161A --wifi rs911x + scripts/examples/gn_efr32_example.sh examples/lighting-app/silabs/efr32/ out/lighting_app_wifi_rs911x BRD4161A --wifi rs911x .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py efr32 BRD4161A+rs911x lighting-app \ out/lighting_app_wifi_rs911x/BRD4161A/chip-efr32-lighting-example.out /tmp/bloat_reports/ + - name: Clean out build output + run: rm -rf ./out - name: Uploading Size Reports uses: actions/upload-artifact@v3 if: ${{ !env.ACT }} diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index 6755e3f64b7bbe..9299ac3822c684 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -71,11 +71,29 @@ jobs: "./scripts/build/build_examples.py \ --enable-flashbundle \ --target esp32-m5stack-all-clusters \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Prepare code pregen and ensure compile time pregen not possible + run: | + ./scripts/run_in_build_env.sh "./scripts/codepregen.py ./zzz_pregenerated" + mv scripts/codegen.py scripts/codegen.py.renamed + - name: Build some M5Stack variations with pregen + timeout-minutes: 60 + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --enable-flashbundle \ --target esp32-m5stack-all-clusters-minimal \ --target esp32-m5stack-all-clusters-rpc-ipv6only \ + --pregen-dir ./zzz_pregenerated \ build \ --copy-artifacts-to out/artifacts \ " + - name: Undo code pregeneration changes + run: | + rm -rf ./zzz_pregenerated + mv scripts/codegen.py.renamed scripts/codegen.py - name: Prepare bloat report run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ diff --git a/.github/workflows/examples-linux-imx.yaml b/.github/workflows/examples-linux-imx.yaml index 2c94f6b37e199f..dbae52ae17833f 100644 --- a/.github/workflows/examples-linux-imx.yaml +++ b/.github/workflows/examples-linux-imx.yaml @@ -50,11 +50,15 @@ jobs: run: | ./scripts/examples/imxlinux_example.sh \ examples/lighting-app/linux/ examples/lighting-app/linux/out/aarch64 + - name: Clean out build output + run: rm -rf ./out - name: Build chip-tool timeout-minutes: 30 run: | ./scripts/examples/imxlinux_example.sh \ examples/chip-tool examples/chip-tool/out/aarch64 + - name: Clean out build output + run: rm -rf ./out - name: Build thermostat timeout-minutes: 30 run: | @@ -62,6 +66,8 @@ jobs: "./scripts/build/build_examples.py \ --target imx-thermostat build \ " + - name: Clean out build output + run: rm -rf ./out - name: Build all-cluster timeout-minutes: 30 run: | @@ -69,6 +75,8 @@ jobs: "./scripts/build/build_examples.py \ --target imx-all-clusters-app build \ " + - name: Clean out build output + run: rm -rf ./out - name: Build all-cluster-minimal timeout-minutes: 30 run: | @@ -76,6 +84,8 @@ jobs: "./scripts/build/build_examples.py \ --target imx-all-clusters-minimal-app build \ " + - name: Clean out build output + run: rm -rf ./out - name: Build ota-provider-app timeout-minutes: 30 run: | @@ -83,3 +93,5 @@ jobs: "./scripts/build/build_examples.py \ --target imx-ota-provider-app build " + - name: Clean out build output + run: rm -rf ./out diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index ecfcc8a2fa5b48..4b9430d38a4b96 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -192,6 +192,41 @@ jobs: nrfconnect nrf5340dk_nrf5340_cpuapp lighting-app \ examples/lighting-app/nrfconnect/build/zephyr/zephyr.elf \ /tmp/bloat_reports/ + - name: Build example nRF Connect SDK Lock App on nRF7002 PDK + if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' + timeout-minutes: 20 + run: | + scripts/examples/nrfconnect_example.sh lock-app nrf7002dk_nrf5340_cpuapp + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf7002dk_nrf5340_cpuapp lock-app \ + examples/lock-app/nrfconnect/build/zephyr/zephyr.elf \ + /tmp/bloat_reports/ + - name: Build example nRF Connect SDK Light Switch App on nRF7002 PDK + if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' + timeout-minutes: 20 + run: | + scripts/examples/nrfconnect_example.sh light-switch-app nrf7002dk_nrf5340_cpuapp + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf7002dk_nrf5340_cpuapp light-switch-app \ + examples/light-switch-app/nrfconnect/build/zephyr/zephyr.elf \ + /tmp/bloat_reports/ + - name: Build example nRF Connect SDK Lighting App on nRF7002 PDK + if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' + timeout-minutes: 20 + run: | + scripts/examples/nrfconnect_example.sh lighting-app nrf7002dk_nrf5340_cpuapp + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf7002dk_nrf5340_cpuapp lighting-app \ + examples/light-switch-app/nrfconnect/build/zephyr/zephyr.elf \ + /tmp/bloat_reports/ + - name: Build example nRF Connect SDK All Clusters App on nRF7002 PDK + timeout-minutes: 20 + run: | + scripts/examples/nrfconnect_example.sh all-clusters-app nrf7002dk_nrf5340_cpuapp + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf7002dk_nrf5340_cpuapp all-clusters-app \ + examples/all-clusters-app/nrfconnect/build/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Run unit tests for Zephyr native_posix_64 platform if: github.event_name == 'push' || steps.changed_paths.outputs.tests == 'true' timeout-minutes: 15 diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 5f040337578fb3..d4f1a9bd8f0991 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -99,6 +99,15 @@ jobs: out/telink-tlsr9518adk80d-ota-requestor/zephyr/zephyr.elf \ /tmp/bloat_reports/ + - name: Build example Telink Thermostat App + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-thermostat' build" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + telink tlsr9518adk80d thermostat \ + out/telink-tlsr9518adk80d-thermostat/zephyr/zephyr.elf \ + /tmp/bloat_reports/ + - name: Uploading Size Reports uses: actions/upload-artifact@v3 if: ${{ !env.ACT }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bf38a3d91a8728..7e468d2e0acb87 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -103,6 +103,8 @@ jobs: if [ "$idl_file" = "./scripts/idl/tests/inputs/optional_argument.matter" ]; then continue; fi if [ "$idl_file" = "./scripts/idl/tests/inputs/several_clusters.matter" ]; then continue; fi if [ "$idl_file" = "./scripts/idl/tests/inputs/simple_attribute.matter" ]; then continue; fi + if [ "$idl_file" = "./scripts/idl/tests/inputs/large_lighting_app.matter" ]; then continue; fi + if [ "$idl_file" = "./scripts/idl/tests/inputs/large_all_clusters_app.matter" ]; then continue; fi ./scripts/run_in_build_env.sh "./scripts/idl_lint.py --log-level warn $idl_file" >/dev/null || exit 1 done diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index a75eb44f7b0b1d..7382354870e6b3 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -408,6 +408,70 @@ jobs: path: objdir-clone/ # objdirs are big; don't hold on to them too long. retention-days: 5 + java_tests_linux: + name: Java Tests - Linux + timeout-minutes: 130 + + env: + TSAN_OPTIONS: "halt_on_error=1 suppressions=scripts/tests/chiptest/tsan-linux-suppressions.txt" + JAVA_PATH: /usr/lib/jvm/java-8-openjdk-amd64 + + if: github.actor != 'restyled-io[bot]' + runs-on: ubuntu-latest + + container: + image: connectedhomeip/chip-build:0.6.06 + options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 + net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" + + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Checkout submodules + run: scripts/checkout_submodules.py --shallow --platform linux + - name: Try to ensure the directories for core dumping exist and we + can write them. + run: | + mkdir /tmp/cores || true + sysctl -w kernel.core_pattern=/tmp/cores/core.%u.%p.%t || true + mkdir objdir-clone || true + - name: Bootstrap + timeout-minutes: 10 + run: scripts/build/gn_bootstrap.sh + - name: Uploading bootstrap logs + uses: actions/upload-artifact@v3 + if: ${{ always() && !env.ACT }} + with: + name: bootstrap-logs-linux-${{ matrix.build_variant }}${{ matrix.chip_tool }} + path: | + .environment/gn_out/.ninja_log + .environment/pigweed-venv/*.log + - name: Build Java Mattter Controller and all clusters app + timeout-minutes: 50 + run: | + scripts/run_in_build_env.sh './scripts/build_python.sh --install_wheel build-env' + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test \ + --target linux-x64-java-matter-controller \ + build \ + " + - name: Uploading core files + uses: actions/upload-artifact@v3 + if: ${{ failure() && !env.ACT }} + with: + name: crash-core-linux-java-controller + path: /tmp/cores/ + # Cores are big; don't hold on to them too long. + retention-days: 5 + - name: Uploading objdir for debugging + uses: actions/upload-artifact@v3 + if: ${{ failure() && !env.ACT }} + with: + name: crash-objdir-linux-java-controller + path: objdir-clone/ + # objdirs are big; don't hold on to them too long. + retention-days: 5 repl_tests_darwin: name: REPL Tests - Darwin diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index db0b2730a651e3..de120fdf4ce363 100644 --- a/.github/workflows/zap_regeneration.yaml +++ b/.github/workflows/zap_regeneration.yaml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build-zap:0.6.06 + image: connectedhomeip/chip-build:0.6.15 defaults: run: shell: sh @@ -44,17 +44,11 @@ jobs: token: ${{ github.token }} attempt_limit: 3 attempt_delay: 2000 - - name: Setup ZAP - timeout-minutes: 5 - run: | - cd third_party/zap/repo/ - npm ci - npm run version-stamp - npm rebuild canvas --update-binary - npm run build-spa - name: Generate all timeout-minutes: 5 run: scripts/tools/zap_regen_all.py + - name: Ensure git works in current working directory + run: git config --global --add safe.directory `pwd` - name: Add uncommitted changes run: git add . - name: Fix upstream diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index 6bb30919015855..1e7713b13c1b27 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build-zap:0.6.06 + image: connectedhomeip/chip-build:0.6.15 defaults: run: shell: sh @@ -44,18 +44,10 @@ jobs: token: ${{ github.token }} attempt_limit: 3 attempt_delay: 2000 - - name: Checkout submodules - run: scripts/checkout_submodules.py --shallow --platform linux - - name: Setup ZAP - timeout-minutes: 10 - run: | - cd third_party/zap/repo/ - npm ci - npm run version-stamp - npm rebuild canvas --update-binary - npm run build-spa - name: Generate all run: scripts/tools/zap_regen_all.py + - name: Ensure git works in current working directory + run: git config --global --add safe.directory `pwd` - name: Check for uncommited changes run: | git add . diff --git a/.gitmodules b/.gitmodules index 5b8d0b466a3b40..1d0e33d8b1f0f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -52,17 +52,13 @@ [submodule "qpg_sdk"] path = third_party/qpg_sdk/repo url = https://github.com/Qorvo/QMatter - branch = v0.9.0.0-libs + branch = vlatest-libs platforms = qpg -[submodule "zap"] - path = third_party/zap/repo - url = https://github.com/project-chip/zap.git - branch = master [submodule "freertos"] path = third_party/freertos/repo url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git branch = V10.3.1-kernel-only - platforms = ameba,cc13x2_26x2,bl602,efr32,esp32,k32w0,infineon,qpg + platforms = ameba,cc13x2_26x2,bouffalolab,efr32,esp32,k32w0,infineon,qpg [submodule "simw-top-mini"] path = third_party/simw-top-mini/repo url = https://github.com/NXP/plug-and-trust.git @@ -268,11 +264,6 @@ [submodule "third_party/boringssl/repo/src"] path = third_party/boringssl/repo/src url = https://github.com/google/boringssl.git -[submodule "boufalolab_repo"] - path = third_party/bouffalolab/repo - url = https://github.com/bouffalolab/bl_iot_sdk.git - branch = master - platforms = bouffalolab,bl602 [submodule "third_party/mt793x_sdk/filogic"] path = third_party/mt793x_sdk/filogic url = https://github.com/MediaTek-Labs/genio-matter-bsp.git @@ -297,4 +288,9 @@ path = third_party/open-iot-sdk/storage url = https://git.gitlab.arm.com/iot/open-iot-sdk/storage.git branch = main - platforms = openiotsdk + platforms = openiotsdk +[submodule "bouffalolab_sdk"] + path = third_party/bouffalolab/repo + url = https://github.com/bouffalolab/bl_iot_sdk_tiny.git + branch = main + platforms = bouffalolab diff --git a/.gn b/.gn index 5da05d85b4d8e0..9577b6db802e79 100644 --- a/.gn +++ b/.gn @@ -29,9 +29,6 @@ default_args = { pw_build_PIP_CONSTRAINTS = [ "//scripts/constraints.txt" ] pw_build_PIP_REQUIREMENTS = [ "//scripts/requirements.txt" ] - # Use the new Python build and merged 'pigweed' Python package. - pw_build_USE_NEW_PYTHON_BUILD = true - # GN target to use for the default Python build venv. pw_build_PYTHON_BUILD_VENV = "//:matter_build_venv" } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 56b9357689ad19..f8cf998bd15e2a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -434,6 +434,7 @@ "telink-tlsr9518adk80d-light", "telink-tlsr9518adk80d-light-switch", "telink-tlsr9518adk80d-ota-requestor", + "telink-tlsr9518adk80d-thermostat", "tizen-arm-light" ] }, diff --git a/BUILD.gn b/BUILD.gn index e21616f90f9a87..e4e1b8e02da1b5 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -103,7 +103,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { "$dir_pw_watch/py", ] - # Matter's in-tree pw_python_package or pw_create_python_source_tree targets. + # Matter's in-tree pw_python_package or pw_python_distribution targets. _matter_python_packages = [ "//integrations/mobly:chip_mobly", "//examples/chef", @@ -119,7 +119,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { source_packages = _matter_python_packages + _pigweed_python_packages } - pw_internal_pip_install("pip_install_matter_packages") { + pw_python_pip_install("pip_install_matter_packages") { packages = [ "//examples/common/pigweed/rpc_console:chip_rpc_distribution" ] } @@ -133,7 +133,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { } # These pw_python_package targets will be installed using 'pip install --editable' - pw_internal_pip_install("pip_install_editable_matter_packages") { + pw_python_pip_install("pip_install_editable_matter_packages") { packages = [ "//integrations/mobly:chip_mobly", "//examples/chef", diff --git a/build/chip/chip_codegen.cmake b/build/chip/chip_codegen.cmake index d0c20c0bd99976..885d189f43f6de 100644 --- a/build/chip/chip_codegen.cmake +++ b/build/chip/chip_codegen.cmake @@ -31,40 +31,71 @@ function(chip_codegen TARGET_NAME) ${ARGN} ) - set(GEN_FOLDER "${CMAKE_BINARY_DIR}/gen/${TARGET_NAME}/${ARG_GENERATOR}") + set(CHIP_CODEGEN_PREGEN_DIR "" CACHE PATH "Pre-generated directory to use instead of compile-time code generation.") - string(REPLACE ";" "\n" OUTPUT_AS_NEWLINES "${ARG_OUTPUTS}") + if ("${CHIP_CODEGEN_PREGEN_DIR}" STREQUAL "") + set(GEN_FOLDER "${CMAKE_BINARY_DIR}/gen/${TARGET_NAME}/${ARG_GENERATOR}") - file(MAKE_DIRECTORY "${GEN_FOLDER}") - file(GENERATE - OUTPUT "${GEN_FOLDER}/expected.outputs" - CONTENT "${OUTPUT_AS_NEWLINES}" - ) + string(REPLACE ";" "\n" OUTPUT_AS_NEWLINES "${ARG_OUTPUTS}") + file(MAKE_DIRECTORY "${GEN_FOLDER}") + file(GENERATE + OUTPUT "${GEN_FOLDER}/expected.outputs" + CONTENT "${OUTPUT_AS_NEWLINES}" + ) + + + set(OUT_NAMES) + foreach(NAME IN LISTS ARG_OUTPUTS) + list(APPEND OUT_NAMES "${GEN_FOLDER}/${NAME}") + endforeach() + + # Python is expected to be in the path + # + # find_package(Python3 REQUIRED) + add_custom_command( + OUTPUT ${OUT_NAMES} + COMMAND "${CHIP_ROOT}/scripts/codegen.py" + ARGS "--generator" "${ARG_GENERATOR}" + "--output-dir" "${GEN_FOLDER}" + "--expected-outputs" "${GEN_FOLDER}/expected.outputs" + "${ARG_INPUT}" + DEPENDS + "${ARG_INPUT}" + VERBATIM + ) + + add_custom_target(${TARGET_NAME} DEPENDS "${OUT_NAMES}") + + # Forward outputs to the parent + set(${ARG_OUTPUT_FILES} "${OUT_NAMES}" PARENT_SCOPE) + set(${ARG_OUTPUT_PATH} "${GEN_FOLDER}" PARENT_SCOPE) + else() + # Gets a path such as: + # examples/lock-app/lock-common/lock-app.matter + file(RELATIVE_PATH MATTER_FILE_PATH "${CHIP_ROOT}" ${ARG_INPUT}) + + # Removes the trailing file extension to get something like: + # examples/lock-app/lock-common/lock-app + string(REGEX REPLACE "\.matter$" "" CODEGEN_DIR_PATH "${MATTER_FILE_PATH}") + + + # Build the final location within the pregen directory + set(GEN_FOLDER "${CHIP_CODEGEN_PREGEN_DIR}/${CODEGEN_DIR_PATH}/codegen/${ARG_GENERATOR}") + + # TODO: build a fake target of ${TARGET_NAME} + + # Here we have ${CHIP_CODEGEN_PREGEN_DIR} + set(OUT_NAMES) + foreach(NAME IN LISTS ARG_OUTPUTS) + list(APPEND OUT_NAMES "${GEN_FOLDER}/${NAME}") + endforeach() - set(OUT_NAMES) - foreach(NAME IN LISTS ARG_OUTPUTS) - list(APPEND OUT_NAMES "${GEN_FOLDER}/${NAME}") - endforeach() - - # Python is expected to be in the path - # - # find_package(Python3 REQUIRED) - add_custom_command( - OUTPUT "${OUT_NAMES}" - COMMAND "${CHIP_ROOT}/scripts/codegen.py" - ARGS "--generator" "${ARG_GENERATOR}" - "--output-dir" "${GEN_FOLDER}" - "--expected-outputs" "${GEN_FOLDER}/expected.outputs" - "${ARG_INPUT}" - DEPENDS - "${ARG_INPUT}" - VERBATIM - ) - add_custom_target(${TARGET_NAME} DEPENDS "${OUT_NAMES}") + set(${ARG_OUTPUT_FILES} "${OUT_NAMES}" PARENT_SCOPE) + set(${ARG_OUTPUT_PATH} "${GEN_FOLDER}" PARENT_SCOPE) - # Forward outputs to the parent - set(${ARG_OUTPUT_FILES} "${OUT_NAMES}" PARENT_SCOPE) - set(${ARG_OUTPUT_PATH} "${GEN_FOLDER}" PARENT_SCOPE) + # allow adding dependencies to a phony target since no codegen is done + add_custom_target(${TARGET_NAME}) + endif() endfunction() diff --git a/build/chip/chip_codegen.gni b/build/chip/chip_codegen.gni index bab79934bd37f5..fd5d69c40c513f 100644 --- a/build/chip/chip_codegen.gni +++ b/build/chip/chip_codegen.gni @@ -18,6 +18,75 @@ import("//build_overrides/pigweed.gni") import("$dir_pw_build/python.gni") +declare_args() { + # Location where code has been pre-generated + chip_code_pre_generated_directory = "" +} + +# Code generation that will happen at build time. +# +# +template("_chip_build_time_codegen") { + _name = target_name + _generator = invoker.generator + + config("${_name}_config") { + include_dirs = [ target_gen_dir ] + } + + pw_python_action("${_name}_codegen") { + script = "${chip_root}/scripts/codegen.py" + + _idl_file = invoker.input + _expected_outputs = "${target_gen_dir}/${_name}.expected.outputs" + + write_file(_expected_outputs, invoker.outputs, "list lines") + + args = [ + "--generator", + _generator, + "--output-dir", + rebase_path(target_gen_dir, root_build_dir), + "--expected-outputs", + rebase_path(_expected_outputs, root_build_dir), + rebase_path(_idl_file, root_build_dir), + ] + + deps = [ "${chip_root}/scripts/idl" ] + + inputs = [ + _idl_file, + _expected_outputs, + ] + sources = [ _idl_file ] + + outputs = [] + foreach(name, invoker.outputs) { + outputs += [ "${target_gen_dir}/${name}" ] + } + } + + source_set(_name) { + sources = [] + foreach(name, invoker.outputs) { + sources += [ "${target_gen_dir}/${name}" ] + } + + public_configs = [ ":${_name}_config" ] + + if (defined(invoker.public_configs)) { + public_configs += invoker.public_configs + } + + forward_variables_from(invoker, [ "deps" ]) + + if (!defined(deps)) { + deps = [] + } + deps += [ ":${_name}_codegen" ] + } +} + # Defines a target that runs code generation based on # scripts/codegen.py # @@ -32,13 +101,29 @@ import("$dir_pw_build/python.gni") # Explicit names of the expected outputs. Enforced to validate that # expected outputs are generated when processing input files. # +# deps, public_configs +# Forwarded to the resulting source set +# +# Command line parameters: +# +# chip_code_pre_generated_directory: +# - If this is set, generation will NOT happen at compile time but rather +# the code generation is assumed to have already happened and reside in +# the given location. +# - The TOP LEVEL directory is assumed to be given. Actual location for +# individual generators is expected to be of the form +# // +# # NOTE: content of "outputs" is verified to match the output of codegen.py # exactly. It is not inferred on purpose, to make build-rules explicit -# and verifiable (even though codege.py can at runtime report its outputs) +# and verifiable (even though codegen.py can at runtime report its outputs) # # To find the list of generated files, you can run codegen.py with the # "--name-only" argument # +# NOTE: +# the result of the target_name WILL BE a `source_set`. Treat it as such. +# # Example usage: # # chip_codegen("java-jni-generate") { @@ -53,43 +138,46 @@ import("$dir_pw_build/python.gni") # } # template("chip_codegen") { - _name = target_name - _generator = invoker.generator - - config("${_name}_config") { - include_dirs = [ target_gen_dir ] - } + if (chip_code_pre_generated_directory == "") { + _chip_build_time_codegen(target_name) { + forward_variables_from(invoker, + [ + "deps", + "generator", + "input", + "outputs", + "public_configs", + ]) + } + } else { + _name = target_name - pw_python_action(_name) { - script = "${chip_root}/scripts/codegen.py" + # This contstructs a path like: + # FROM all-clusters-app.matter (inside examples/all-clusters-app/all-clusters-common/) + # USING "cpp-app" for generator: + # => ${pregen_dir}/examples/all-clusters-app/all-clusters-common/all-clusters-app/codegen/cpp-app + _generation_dir = + chip_code_pre_generated_directory + "/" + + string_replace(rebase_path(invoker.input, chip_root), ".matter", "") + + "/codegen/" + invoker.generator - _idl_file = invoker.input - _expected_outputs = "${target_gen_dir}/${_name}.expected.outputs" - - write_file(_expected_outputs, invoker.outputs, "list lines") + config("${_name}_config") { + include_dirs = [ "${_generation_dir}" ] + } - args = [ - "--generator", - _generator, - "--output-dir", - rebase_path(target_gen_dir, root_build_dir), - "--expected-outputs", - rebase_path(_expected_outputs, root_build_dir), - rebase_path(_idl_file, root_build_dir), - ] + source_set(_name) { + public_configs = [ ":${_name}_config" ] - deps = [ "${chip_root}/scripts/idl" ] - public_configs = [ ":${_name}_config" ] + if (defined(invoker.public_configs)) { + public_configs += invoker.public_configs + } - inputs = [ - _idl_file, - _expected_outputs, - ] - sources = [ _idl_file ] + forward_variables_from(invoker, [ "deps" ]) - outputs = [] - foreach(name, invoker.outputs) { - outputs += [ "${target_gen_dir}/${name}" ] + sources = [] + foreach(name, invoker.outputs) { + sources += [ "${_generation_dir}/${name}" ] + } } } } diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index caaf06f5028f2b..336450ca459487 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -94,15 +94,9 @@ template("chip_test_suite") { public_deps = [] } - # TODO: figure out a way to auto-define dependency on stdio logging. - # This dep is required since libSupportLayer now does not include - # a default implementation. - # - # Tests such as TestInetEndPoint need to exercise the system event - # loop however they do not seem to include a logging binding so this - # is forcefully added here. if (current_os != "zephyr" && current_os != "mbed") { - public_deps += [ "${chip_root}/src/platform/logging:stdio" ] + # Depend on stdio logging, and have it take precedence over the default platform backend + public_deps += [ "${chip_root}/src/platform/logging:force_stdio" ] } } diff --git a/build/chip/esp32/esp32_codegen.cmake b/build/chip/esp32/esp32_codegen.cmake index 8d454e369dc75c..f9e0479662b1a2 100644 --- a/build/chip/esp32/esp32_codegen.cmake +++ b/build/chip/esp32/esp32_codegen.cmake @@ -34,6 +34,7 @@ macro(chip_app_component_codegen IDL_NAME) GENERATOR "cpp-app" OUTPUTS "app/PluginApplicationCallbacks.h" + "app/callback-stub.cpp" OUTPUT_PATH APP_GEN_DIR OUTPUT_FILES APP_GEN_FILES ) @@ -41,5 +42,7 @@ macro(chip_app_component_codegen IDL_NAME) target_include_directories(${COMPONENT_LIB} PUBLIC "${APP_GEN_DIR}") add_dependencies(${COMPONENT_LIB} app-codegen) + + target_sources(${COMPONENT_LIB} PRIVATE ${APP_GEN_FILES}) endif() endmacro() diff --git a/build/chip/java/config.gni b/build/chip/java/config.gni new file mode 100644 index 00000000000000..626d7b00e2a669 --- /dev/null +++ b/build/chip/java/config.gni @@ -0,0 +1,26 @@ +# 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. + +java_path = getenv("JAVA_PATH") +declare_args() { + java_matter_controller_dependent_paths = [] + build_java_matter_controller = false + if (java_path != "") { + java_matter_controller_dependent_paths += [ + "${java_path}/include/", + "${java_path}/include/linux/", + ] + build_java_matter_controller = true + } +} diff --git a/build/chip/java/rules.gni b/build/chip/java/rules.gni index c8518303f121dd..446bad701931f1 100644 --- a/build/chip/java/rules.gni +++ b/build/chip/java/rules.gni @@ -13,14 +13,15 @@ # limitations under the License. import("//build_overrides/chip.gni") - +import("${chip_root}/build/chip/java/config.gni") import("${chip_root}/build/config/android/config.gni") javac_runner = "${chip_root}/build/chip/java/javac_runner.py" jar_runner = "${chip_root}/build/chip/java/jar_runner.py" write_build_config = "${chip_root}/build/chip/java/write_build_config.py" -assert(android_sdk_root != "", "android_sdk_root must be specified") +assert(android_sdk_root != "" || build_java_matter_controller, + "android_sdk_root or java_path must be specified") # Declare a java library target # diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 938d2d7e405835..96cdcd00256e3f 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -14,7 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/pigweed.gni") - +import("${build_root}/chip/java/config.gni") import("${build_root}/config/compiler/compiler.gni") import("${build_root}/config/sysroot.gni") import("${build_root}/config/target.gni") @@ -194,9 +194,8 @@ config("optimize_default") { config("disabled_warnings") { cflags = [ "-Wno-deprecated-declarations", - "-Wno-unknown-warning-option", - "-Wno-maybe-uninitialized", "-Wno-missing-field-initializers", + "-Wno-unknown-warning-option", "-Wno-unused-parameter", ] if (!is_debug) { @@ -205,8 +204,9 @@ config("disabled_warnings") { } if (!is_clang) { cflags += [ - "-Wno-psabi", "-Wno-cast-function-type", + "-Wno-psabi", + "-Wno-maybe-uninitialized", ] } } @@ -248,6 +248,10 @@ config("strict_warnings") { ] } + if (build_java_matter_controller) { + cflags -= [ "-Wshadow" ] + } + cflags_cc = [ "-Wnon-virtual-dtor" ] ldflags = [] @@ -287,9 +291,12 @@ config("disabled_warnings_third_party") { cflags = [ "-Wno-unused", "-Wno-format", - "-Wno-maybe-uninitialized", "-Wno-address", ] + + if (!is_clang) { + cflags += [ "-Wno-maybe-uninitialized" ] + } } config("warnings_third_party") { diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni index 9f3380e9af5eba..0e7f02b5bb3399 100644 --- a/build/config/mac/mac_sdk.gni +++ b/build/config/mac/mac_sdk.gni @@ -28,7 +28,7 @@ if (current_os != "mac") { target_sdk = current_os } -deployment_target = "10.15" +deployment_target = "11.0" if (current_os == "mac") { if (current_cpu == "arm64") { deployment_target = "11.0" diff --git a/build_overrides/bouffalolab_iot_sdk.gni b/build_overrides/bouffalolab_iot_sdk.gni index 165bf5944f16d8..77ab3440927271 100644 --- a/build_overrides/bouffalolab_iot_sdk.gni +++ b/build_overrides/bouffalolab_iot_sdk.gni @@ -19,6 +19,5 @@ declare_args() { # Root directory for bl702 SDK build files. bl702_sdk_build_root = "//third_party/bouffalolab/bl702" - # Root directory of toolchain of Bouffalolab chips - bouffalolab_toolchain = "//third_party/bouffalolab/repo/toolchain/riscv" + bouffalolab_sdk_root = "/opt/bouffalolab_sdk" } diff --git a/config/ameba/args.gni b/config/ameba/args.gni index d09b1f5cba9843..7d3d91a602ccf4 100755 --- a/config/ameba/args.gni +++ b/config/ameba/args.gni @@ -16,7 +16,6 @@ # options are used from examples/. import("//build_overrides/pigweed.gni") -import("$dir_pw_span/polyfill.gni") chip_device_platform = "ameba" @@ -38,5 +37,4 @@ custom_toolchain = "//third_party/connectedhomeip/config/ameba/toolchain:ameba" pw_build_PIP_CONSTRAINTS = [ "//third_party/connectedhomeip/scripts/constraints.txt" ] -pw_span_ENABLE_STD_SPAN_POLYFILL = false cpp_standard = "c++17" diff --git a/config/ameba/chip.cmake b/config/ameba/chip.cmake index a6e696882a0c9d..515bff64ef99c9 100644 --- a/config/ameba/chip.cmake +++ b/config/ameba/chip.cmake @@ -30,6 +30,7 @@ list( -DCHIP_DEVICE_LAYER_TARGET=Ameba -DMBEDTLS_CONFIG_FILE= -D_POSIX_REALTIME_SIGNALS + -DCHIP_SHELL_MAX_TOKENS=11 ) list( diff --git a/config/bouffalolab/common/lib/pw_rpc/pw_rpc.gni b/config/bouffalolab/common/lib/pw_rpc/pw_rpc.gni index c8300fa010d569..2cfbc034e875eb 100644 --- a/config/bouffalolab/common/lib/pw_rpc/pw_rpc.gni +++ b/config/bouffalolab/common/lib/pw_rpc/pw_rpc.gni @@ -19,7 +19,6 @@ pw_log_BACKEND = "$dir_pw_log_basic" pw_assert_BACKEND = "$dir_pw_assert_log" pw_sys_io_BACKEND = "${chip_root}/examples/platform/bouffalolab/common/rpc/pw_sys_io:pw_sys_io" -pw_span_ENABLE_STD_SPAN_POLYFILL = false pw_string_CONFIG = "${chip_root}/config/bouffalolab/common/lib/pw_rpc:pw_string_dep" diff --git a/config/efr32/lib/pw_rpc/BUILD.gn b/config/efr32/lib/pw_rpc/BUILD.gn index 390ced7920eda9..32a95488dbdf30 100644 --- a/config/efr32/lib/pw_rpc/BUILD.gn +++ b/config/efr32/lib/pw_rpc/BUILD.gn @@ -24,7 +24,7 @@ static_library("pw_rpc") { public_deps = [ "$dir_pw_rpc:server", "$dir_pw_rpc/nanopb:echo_service", - "${chip_root}/examples/platform/efr32/pw_sys_io:pw_sys_io_efr32", + "${chip_root}/examples/platform/silabs/efr32/pw_sys_io:pw_sys_io_efr32", "${dir_pigweed}/pw_hdlc:pw_rpc", dir_pw_assert, dir_pw_checksum, diff --git a/config/efr32/lib/pw_rpc/pw_rpc.gni b/config/efr32/lib/pw_rpc/pw_rpc.gni index 2c8aaf4d14fba1..5fd576d93c4a98 100644 --- a/config/efr32/lib/pw_rpc/pw_rpc.gni +++ b/config/efr32/lib/pw_rpc/pw_rpc.gni @@ -18,8 +18,7 @@ import("//build_overrides/pigweed.gni") pw_log_BACKEND = "$dir_pw_log_basic" pw_assert_BACKEND = "$dir_pw_assert_log:check_backend" pw_sys_io_BACKEND = - "${chip_root}/examples/platform/efr32/pw_sys_io:pw_sys_io_efr32" -pw_span_ENABLE_STD_SPAN_POLYFILL = false + "${chip_root}/examples/platform/silabs/efr32/pw_sys_io:pw_sys_io_efr32" pw_build_LINK_DEPS = [ "$dir_pw_assert:impl", diff --git a/config/esp32/.gn b/config/esp32/.gn index 2cb77a0fa8950c..4b3520ab15c9a6 100644 --- a/config/esp32/.gn +++ b/config/esp32/.gn @@ -24,5 +24,10 @@ default_args = { target_cpu = "esp32" target_os = "freertos" + pw_build_PIP_CONSTRAINTS = + [ "//third_party/connectedhomeip/scripts/constraints.txt" ] + pw_build_PIP_REQUIREMENTS = + [ "//third_party/connectedhomeip/scripts/requirements.txt" ] + import("//args.gni") } diff --git a/config/esp32/args.gni b/config/esp32/args.gni index 1f6a6bf0987103..939c39e85b8e2d 100644 --- a/config/esp32/args.gni +++ b/config/esp32/args.gni @@ -15,7 +15,6 @@ # Options from standalone-chip.mk that differ from configure defaults. These # options are used from examples/. import("//build_overrides/pigweed.gni") -import("$dir_pw_span/polyfill.gni") chip_device_platform = "esp32" chip_project_config_include = "" @@ -39,4 +38,3 @@ custom_toolchain = "//third_party/connectedhomeip/config/esp32/toolchain:esp32" # whatever pigweed ships with pw_build_PIP_CONSTRAINTS = [ "//third_party/connectedhomeip/scripts/constraints.txt" ] -pw_span_ENABLE_STD_SPAN_POLYFILL = false diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index a8b1be9bab9a53..d7cb69a6a8fa34 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -101,6 +101,10 @@ if(CONFIG_DISABLE_IPV4) chip_gn_arg_append("chip_inet_config_enable_ipv4" "false") endif() +if(CHIP_CODEGEN_PREGEN_DIR) + chip_gn_arg_append("chip_code_pre_generated_directory" "\"${CHIP_CODEGEN_PREGEN_DIR}\"") +endif() + if(CONFIG_ENABLE_PW_RPC) string(APPEND chip_gn_args "import(\"//build_overrides/pigweed.gni\")\n") chip_gn_arg_append("remove_default_configs" "[\"//third_party/connectedhomeip/third_party/pigweed/repo/pw_build:toolchain_cpp_standard\"]") @@ -119,8 +123,8 @@ if (CONFIG_BUILD_CHIP_TESTS) chip_gn_arg_bool("chip_build_tests" "true") endif() -if (CONFIG_CHIP_ENABLE_SCHEMA_CHECK) - chip_gn_arg_bool("chip_enable_schema_check" "true") +if (CONFIG_IM_PRETTY_PRINT) + chip_gn_arg_bool("enable_im_pretty_print" "true") endif() if (NOT CONFIG_USE_MINIMAL_MDNS) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index 7a9e3ab54323c6..d86215bc57ce9d 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -227,7 +227,7 @@ menu "CHIP Device Layer" default 25 help The maximum number of events that can be held in the CHIP Platform event queue. - + config ENABLE_EXTENDED_DISCOVERY bool "Enable Extended discovery Support" default n @@ -474,7 +474,7 @@ menu "CHIP Device Layer" config USE_BLE_ONLY_FOR_COMMISSIONING bool "Use BLE only for commissioning" default y - help + help Disable this flag if BLE is used for any other purpose than commissioning. When enabled, it deinitialized the BLE on successful commissioning, and on bootup do not initialize the BLE if device is already provisioned with Wi-Fi/Thread credentials. @@ -657,6 +657,13 @@ menu "CHIP Device Layer" Details like Supported calendar types, supported locales, and fixed labels will be read from factory partition. + config ENABLE_ESP32_LOCATIONCAPABILITY + depends on ENABLE_ESP32_FACTORY_DATA_PROVIDER + bool "Enable ESP32 Device LocationCapability " + default n + help + Enable ESP32 Device LocationCapability + endmenu @@ -787,12 +794,11 @@ menu "CHIP Device Layer" for the debug level events are disabled. - config CHIP_ENABLE_SCHEMA_CHECK - bool "Enable Schema Check" + config CHIP_CONFIG_IM_PRETTY_PRINT + bool "Enable IM Pretty Print" default y help - If enabled, it checks incoming messages are following the expected schema, - and incoming message payloads are logged in detail. + If enabled, incoming message payloads are logged in detail. To see detailed logging please set default log level to Debug. (Component config --> Log output --> Default log verbosity --> Debug) @@ -850,7 +856,7 @@ menu "CHIP Device Layer" default "nvs" help Label of the partition to store key-values in the "chip-counters" namespace. - + config CHIP_KVS_NAMESPACE_PARTITION_LABEL string "chip-kvs namespace partition label" default "nvs" diff --git a/config/mbed/CMakeLists.txt b/config/mbed/CMakeLists.txt index 337020b56c3d62..ecef938c0a8f07 100644 --- a/config/mbed/CMakeLists.txt +++ b/config/mbed/CMakeLists.txt @@ -395,6 +395,7 @@ target_include_directories(${APP_TARGET} PRIVATE ${PIGWEED_ROOT}/pw_log_basic/public_overrides ${PIGWEED_ROOT}/pw_span/public_overrides ${PIGWEED_ROOT}/pw_span/public + ${PIGWEED_ROOT}/pw_string/public ${PIGWEED_ROOT}/pw_sync/public ${PIGWEED_ROOT}/pw_polyfill/public ${PIGWEED_ROOT}/pw_polyfill/standard_library_public @@ -410,6 +411,8 @@ target_include_directories(${APP_TARGET} PRIVATE ${PIGWEED_ROOT}/pw_function/public ${PIGWEED_ROOT}/pw_preprocessor/public ${PIGWEED_ROOT}/pw_rpc/system_server/public + ${PIGWEED_ROOT}/third_party/fuchsia/repo/sdk/lib/fit/include + ${PIGWEED_ROOT}/third_party/fuchsia/repo/sdk/lib/stdcompat/include ${CHIP_ROOT}/third_party/nanopb/repo ${CHIP_ROOT}/examples/common @@ -489,18 +492,11 @@ if (NOT ${APP_TARGET} MATCHES "shell") ${CHIP_ROOT}/src/app/clusters/ota-requestor/ota-requestor-server.cpp ) else() - include(${CHIP_ROOT}/src/app/chip_data_model.cmake) - chip_configure_data_model(${APP_TARGET} - ZAP_FILE ${CHIP_ROOT}/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap - GEN_DIR ${CHIP_ROOT}/zzz_generated/ota-requestor-app/zap-generated - ) - target_include_directories(${APP_TARGET} PRIVATE - ${GEN_DIR}/ota-requestor-app - ) - target_sources(${APP_TARGET} PRIVATE - ${GEN_DIR}//ota-requestor-app/zap-generated/callback-stub.cpp - ${GEN_DIR}/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp - ) + target_include_directories(${APP_TARGET} + PRIVATE ${GEN_DIR}/ota-requestor-app) + + target_sources(${APP_TARGET} + PRIVATE ${GEN_DIR}/ota-requestor-app/zap-generated/IMClusterCommandHandler.cpp) endif() list(APPEND CHIP_DEFINES diff --git a/config/mbed/chip-gn/lib/pw_rpc/pw_rpc.gni b/config/mbed/chip-gn/lib/pw_rpc/pw_rpc.gni index b2033e5280c539..2b03f6b4c9958c 100644 --- a/config/mbed/chip-gn/lib/pw_rpc/pw_rpc.gni +++ b/config/mbed/chip-gn/lib/pw_rpc/pw_rpc.gni @@ -21,7 +21,6 @@ pw_sys_io_BACKEND = "${chip_root}/examples/platform/mbed/pw_sys_io:pw_sys_io_mbed" pw_rpc_system_server_BACKEND = "${chip_root}/examples/common/pigweed:system_rpc_server" -pw_span_ENABLE_STD_SPAN_POLYFILL = false pw_build_LINK_DEPS = [ "$dir_pw_assert:impl", diff --git a/config/nrfconnect/chip-gn/args.gni b/config/nrfconnect/chip-gn/args.gni index 0ac19884ce2e5e..0963be64b3b289 100644 --- a/config/nrfconnect/chip-gn/args.gni +++ b/config/nrfconnect/chip-gn/args.gni @@ -14,6 +14,8 @@ import("//build_overrides/chip.gni") +import("${chip_root}/src/crypto/crypto.gni") + chip_device_platform = "nrfconnect" chip_build_tests = false @@ -22,6 +24,9 @@ chip_project_config_include = "" chip_system_project_config_include = "" chip_ble_project_config_include = "" +chip_crypto = "mbedtls" +chip_external_mbedtls = true + custom_toolchain = "${chip_root}/config/nrfconnect/chip-gn/toolchain:zephyr" pw_build_PIP_CONSTRAINTS = [ "${chip_root}/scripts/constraints.txt" ] diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 305edd21e9c2e3..68e0e31d19abb5 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -219,6 +219,7 @@ chip_gn_arg_bool ("chip_progress_logging" CONFIG_MATTER_LOG_LE chip_gn_arg_bool ("chip_detail_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 4) chip_gn_arg_bool ("chip_automation_logging" "false") chip_gn_arg_bool ("chip_malloc_sys_heap" CONFIG_CHIP_MALLOC_SYS_HEAP) +chip_gn_arg_bool ("chip_enable_wifi" CONFIG_WIFI_NRF700X) if (CONFIG_CHIP_FACTORY_DATA) chip_gn_arg_bool ("chip_use_transitional_commissionable_data_provider" "false") @@ -232,8 +233,12 @@ if (CONFIG_CHIP_ROTATING_DEVICE_ID) chip_gn_arg_bool("chip_enable_additional_data_advertising" "true") endif() -if (CONFIG_CHIP_ENABLE_DNSSD_SRP) +if (CONFIG_NET_L2_OPENTHREAD) chip_gn_arg_string("chip_mdns" "platform") +elseif(CONFIG_WIFI_NRF700X) + chip_gn_arg_string("chip_mdns" "minimal") +else() + chip_gn_arg_string("chip_mdns" "none") endif() if (CONFIG_CHIP_CRYPTO_PSA) @@ -261,8 +266,6 @@ endif() if (CONFIG_CHIP_PW_RPC) set(PIGWEED_DIR "//third_party/pigweed/repo") - chip_gn_arg_bool("chip_build_pw_trace_lib" "true") - chip_gn_arg_string("pw_trace_BACKEND" ${PIGWEED_DIR}/pw_trace_tokenized) chip_gn_arg_string("pw_assert_BACKEND" ${PIGWEED_DIR}/pw_assert_log:check_backend) chip_gn_arg_string("pw_log_BACKEND" ${PIGWEED_DIR}/pw_log_basic) chip_gn_arg("pw_build_LINK_DEPS" [\"${PIGWEED_DIR}/pw_assert:impl\",\ \"${PIGWEED_DIR}/pw_log:impl\"]) diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig index e4a0a9f3a1abab..ee51bfb15f4b99 100644 --- a/config/nrfconnect/chip-module/Kconfig +++ b/config/nrfconnect/chip-module/Kconfig @@ -18,6 +18,15 @@ rsource "../../zephyr/Kconfig" if CHIP +config CHIP_APP_LOG_LEVEL + int "Set logging level in application" + default LOG_DEFAULT_LEVEL + help + Sets the logging level in Matter application. + This config should be used only within application. + To set the logging level for Matter stack use MATTER_LOG_LEVEL + config. + config CHIP_NFC_COMMISSIONING bool "Enable NFC commissioning support" default n diff --git a/config/nrfconnect/chip-module/Kconfig.defaults b/config/nrfconnect/chip-module/Kconfig.defaults index 228dbaeb478089..e02d0d2981cc71 100644 --- a/config/nrfconnect/chip-module/Kconfig.defaults +++ b/config/nrfconnect/chip-module/Kconfig.defaults @@ -213,20 +213,72 @@ config NVS_LOOKUP_CACHE_SIZE int default 512 +# Enable OpenThread + +config NET_L2_OPENTHREAD + bool + default y if !WIFI_NRF700X + +if NET_L2_OPENTHREAD + # Increase the default RX stack size config IEEE802154_NRF5_RX_STACK_SIZE int default 1024 -# Enable OpenThread +endif -config NET_L2_OPENTHREAD +if CHIP_WIFI + +config NRF_WIFI_LOW_POWER bool - default y + default n + +config MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + bool + default n + +config SYSTEM_WORKQUEUE_STACK_SIZE + int + default 1120 + +# align these numbers to match the OpenThread config +config NET_IF_UNICAST_IPV6_ADDR_COUNT + int + default 6 + +config NET_IF_MCAST_IPV6_ADDR_COUNT + int + default 8 + +config NET_SOCKETS_POSIX_NAMES + bool + default n + +config MBEDTLS_SSL_OUT_CONTENT_LEN + int + default 900 + +# options managed by IP4/IP6 simultaneous support +# aligned here to match OpenThread config +config NET_MAX_ROUTERS + int + default 1 + +config NET_MAX_CONN + int + default 4 + +config SHELL_STACK_SIZE + int + default 2616 + +config HEAP_MEM_POOL_SIZE + int + default 200000 + +endif -choice OPENTHREAD_STACK_VERSION - default OPENTHREAD_THREAD_VERSION_1_3 -endchoice # Enable mbedTLS from nrf_security library diff --git a/config/nrfconnect/chip-module/Kconfig.features b/config/nrfconnect/chip-module/Kconfig.features index 1f12053658f23e..6ff4aa5ea62527 100644 --- a/config/nrfconnect/chip-module/Kconfig.features +++ b/config/nrfconnect/chip-module/Kconfig.features @@ -19,6 +19,31 @@ if CHIP +config CHIP_WIFI + bool "Enable nrfconnect Wi-Fi support" + default y if SHIELD_NRF7002_EK || BOARD_NRF7002DK_NRF5340_CPUAPP + select WIFI_NRF700X + select WIFI + select WPA_SUPP + imply FLASH + imply SETTINGS + imply NVS + imply FLASH_MAP + imply NORDIC_SECURITY_BACKEND + imply MBEDTLS_ENTROPY_C + imply MBEDTLS_PSA_CRYPTO_C + imply NET_STATISTICS + imply NET_L2_ETHERNET + imply NET_PKT_TXTIME + imply NET_PKT_TIMESTAMP + imply MBEDTLS_PROMPTLESS + imply BUILD_OUTPUT_META + imply USE_DT_CODE_PARTITION # might be removed when the OTA is enabled + imply NET_IPV6_ND # enable Neighbor Discovery to handle Router Advertisements + imply NET_IPV6_NBR_CACHE + imply NET_STATISTICS_IPV6 + imply NET_STATISTICS_USER_API + config CHIP_QSPI_NOR bool "Enable QSPI NOR feature set" help diff --git a/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.defaults b/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.defaults new file mode 100644 index 00000000000000..8069d710047338 --- /dev/null +++ b/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.defaults @@ -0,0 +1,99 @@ +# +# 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. +# + +# The purpose of this file is to define new default values of settings used when building hci_rpmsg child image for Matter samples. + +config LOG + bool + default n + +config HEAP_MEM_POOL_SIZE + int + default 8192 + +config MAIN_STACK_SIZE + int + default 2048 + +config SYSTEM_WORKQUEUE_STACK_SIZE + int + default 2048 + +config BT + bool + default y + +config BT_HCI_RAW + bool + default y + +config BT_MAX_CONN + int + default 1 + +config BT_PERIPHERAL + bool + default y + +config BT_CENTRAL + bool + default n + +config BT_BUF_ACL_RX_SIZE + int + default 502 + +config BT_BUF_ACL_TX_SIZE + int + default 251 + +config BT_CTLR_DATA_LENGTH_MAX + int + default 251 + +config BT_CTLR_ASSERT_HANDLER + bool + default y + +config BT_HCI_RAW_RESERVE + int + default 1 + +# Workaround: Unable to allocate command buffer when using K_NO_WAIT since +# Host number of completed commands does not follow normal flow control. +config BT_BUF_CMD_TX_COUNT + int + default 10 + +config ASSERT + bool + default y + +config DEBUG_INFO + bool + default y + +config EXCEPTION_STACK_TRACE + bool + default y + +config IPC_SERVICE + bool + default y + +config MBOX + bool + default y diff --git a/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.root b/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.root new file mode 100644 index 00000000000000..8c4f6eee49cbc2 --- /dev/null +++ b/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.root @@ -0,0 +1,21 @@ +# +# 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. +# + +# The purpose of this file is to create a wrapper Kconfig file that will be set as +# hci_rpmsg_KCONFIG_ROOT and processed before any other Kconfig for hci_rpmsg child image. + +rsource "Kconfig.hci_rpmsg.defaults" +source "Kconfig.zephyr" diff --git a/config/qpg/lib/pw_rpc/pw_rpc.gni b/config/qpg/lib/pw_rpc/pw_rpc.gni index 4100605a1445b1..60fb93e6b8fc44 100644 --- a/config/qpg/lib/pw_rpc/pw_rpc.gni +++ b/config/qpg/lib/pw_rpc/pw_rpc.gni @@ -18,7 +18,6 @@ import("//build_overrides/pigweed.gni") pw_log_BACKEND = "$dir_pw_log_basic" pw_assert_BACKEND = "$dir_pw_assert_log:check_backend" pw_sys_io_BACKEND = "${chip_root}/examples/platform/qpg/pw_sys_io:pw_sys_io_qpg" -pw_span_ENABLE_STD_SPAN_POLYFILL = false pw_build_LINK_DEPS = [ "$dir_pw_assert:impl", diff --git a/config/standalone/args.gni b/config/standalone/args.gni index 32235745930867..89e186b4edb8a4 100644 --- a/config/standalone/args.gni +++ b/config/standalone/args.gni @@ -19,3 +19,4 @@ import("//build_overrides/chip.gni") chip_build_tests = false pw_build_PIP_CONSTRAINTS = [ "${chip_root}/scripts/constraints.txt" ] +pw_build_PIP_REQUIREMENTS = [ "${chip_root}/scripts/requirements.txt" ] diff --git a/config/telink/app/enable-gnu-std.cmake b/config/telink/app/enable-gnu-std.cmake index 38bacbea1ef791..e46c87199aad2d 100644 --- a/config/telink/app/enable-gnu-std.cmake +++ b/config/telink/app/enable-gnu-std.cmake @@ -15,5 +15,5 @@ # add_library(gnu17 INTERFACE) -target_compile_options(gnu17 INTERFACE -std=gnu++17 -D_SYS__PTHREADTYPES_H_) +target_compile_options(gnu17 INTERFACE $<$:-std=gnu++17> -D_SYS__PTHREADTYPES_H_) target_link_libraries(app PRIVATE gnu17) \ No newline at end of file diff --git a/config/telink/chip-gn/args.gni b/config/telink/chip-gn/args.gni index 713a3fd231c159..a84cc321a4bb88 100644 --- a/config/telink/chip-gn/args.gni +++ b/config/telink/chip-gn/args.gni @@ -14,6 +14,8 @@ import("//build_overrides/chip.gni") +import("${chip_root}/src/crypto/crypto.gni") + chip_device_platform = "telink" chip_build_tests = false @@ -22,6 +24,9 @@ chip_project_config_include = "" chip_system_project_config_include = "" chip_ble_project_config_include = "" +chip_crypto = "mbedtls" +chip_external_mbedtls = true + custom_toolchain = "${chip_root}/config/telink/chip-gn/toolchain:zephyr" pw_build_PIP_CONSTRAINTS = [ "${chip_root}/scripts/constraints.txt" ] diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 6ef6ac2c882238..6a48424b7f4832 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -91,6 +91,7 @@ macro(chip_gn_arg ARG VALUE) string(APPEND CHIP_GN_ARGS "--arg\n${ARG}\n${VALUE}\n") endmacro() + # ============================================================================== # Prepare CHIP configuration based on the project Kconfig configuration # ============================================================================== @@ -128,10 +129,6 @@ if (CONFIG_CHIP_LIB_SHELL) list(APPEND CHIP_LIBRARIES -lCHIPShell) endif() -if (CONFIG_CHIP_PW_RPC) - list(APPEND CHIP_LIBRARIES -lPwRpc) -endif() - if (CONFIG_TELINK_BLE_LIB) list(APPEND CHIP_LIBRARIES -lB91_ble_lib) endif() @@ -226,6 +223,14 @@ if (CHIP_PROJECT_CONFIG) chip_gn_arg_string("chip_project_config_include" ${CHIP_PROJECT_CONFIG}) chip_gn_arg_string("chip_system_project_config_include" ${CHIP_PROJECT_CONFIG}) endif() + +if (CONFIG_CHIP_PW_RPC) + set(PIGWEED_DIR "//third_party/pigweed/repo") + chip_gn_arg_string("pw_assert_BACKEND" ${PIGWEED_DIR}/pw_assert_log:check_backend) + chip_gn_arg_string("pw_log_BACKEND" ${PIGWEED_DIR}/pw_log_basic) + chip_gn_arg("pw_build_LINK_DEPS" [\"${PIGWEED_DIR}/pw_assert:impl\",\ \"${PIGWEED_DIR}/pw_log:impl\"]) +endif() + if (CONFIG_CHIP_EXAMPLE_DEVICE_INFO_PROVIDER) chip_gn_arg_bool("chip_build_example_providers" "true") list(APPEND CHIP_LIBRARIES -lMatterDeviceInfoProviderExample) diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index 366c43d8eac6db..f216280df7e583 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -266,3 +266,8 @@ config CHIP_CERTIFiCATION_DECLARATION_OTA_IMAGE_ID for sending it via OTA Software Update purposes. endif + +# See config/zephyr/Kconfig for full definition +config CHIP_FACTORY_RESET_ERASE_NVS + bool + default y diff --git a/config/zephyr/Kconfig b/config/zephyr/Kconfig index 9928bb35b49258..048855d23e2263 100644 --- a/config/zephyr/Kconfig +++ b/config/zephyr/Kconfig @@ -112,7 +112,7 @@ config CHIP_ENABLE_PAIRING_AUTOSTART config CHIP_ENABLE_DNSSD_SRP bool "Enable support for service registration" - default y + default y if NET_L2_OPENTHREAD imply OPENTHREAD_ECDSA imply OPENTHREAD_SRP_CLIENT help @@ -154,10 +154,10 @@ config CHIP_SED_ACTIVE_INTERVAL endif # CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT config CHIP_THREAD_SSED - bool "Enable Thread Synchronized Sleepy End Device support" - depends on OPENTHREAD_CSL_RECEIVER && CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT - help - Enables Thread Synchronized Sleepy End Device support in Matter. + bool "Enable Thread Synchronized Sleepy End Device support" + depends on OPENTHREAD_CSL_RECEIVER && CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT + help + Enables Thread Synchronized Sleepy End Device support in Matter. config CHIP_OTA_REQUESTOR bool "Enable OTA requestor" diff --git a/config/zephyr/chip-gn/args.gni b/config/zephyr/chip-gn/args.gni index e5d5aedf5bc17d..1421e79aa80edd 100644 --- a/config/zephyr/chip-gn/args.gni +++ b/config/zephyr/chip-gn/args.gni @@ -14,6 +14,8 @@ import("//build_overrides/chip.gni") +import("${chip_root}/src/crypto/crypto.gni") + chip_device_platform = "zephyr" chip_build_tests = false @@ -22,6 +24,9 @@ chip_project_config_include = "" chip_system_project_config_include = "" chip_ble_project_config_include = "" +chip_crypto = "mbedtls" +chip_external_mbedtls = true + custom_toolchain = "${chip_root}/config/zephyr/chip-gn/toolchain:zephyr" pw_build_PIP_CONSTRAINTS = [ "${chip_root}/scripts/constraints.txt" ] diff --git a/docs/code_generation.md b/docs/code_generation.md new file mode 100644 index 00000000000000..7deed7ba05fb1a --- /dev/null +++ b/docs/code_generation.md @@ -0,0 +1,208 @@ +# Code generation + +## Code generation inputs (`*.zap` files) + +Matter code relies on code generation for cluster-specific data types and +callbacks. Generally this is split into: + +- Data serialization for structures/lists/commands. This applies to both + client-side and server-side structures and objects +- Callback setup using the Ember-based framework. This generally applies to + server-side processing and the code generation defines what processing needs + to be done when a specific command is received or an attribute is read and + what memory should be allocated for storing cluster attributes + +Code generation depends on the clusters that are needed by an application. Every +application configures the specific set of endpoints and clusters it needs based +on the device type it supports. The selection of the supported clusters and +attributes (as optional attributes may be omitted to save memory) is generally +stored in `*.zap` files. + +The selection of enabled clusters and files is done using +[ZAP](https://github.com/project-chip/zap). You can download a recent release of +zap from its [releases page](https://github.com/project-chip/zap/releases). It +is recommended to download a release that is in sync with the currently in use +version by the SDK (see `integrations/docker/images/chip-build/Dockerfile` and +check the `ZAP_VERSION` setting). + +Beyond basic zap file selection, there are also `.json` zap settings that define +additional cluster info: source XML files, sdk-access methods and data types. +There are only two such files currently in use: + +- `src/app/zap-templates/zcl/zcl.json` is the **default** one +- `src/app/zap-templates/zcl/zcl-with-test-extensions.json` is used by + `all-clusters-app` to show how a cluster extension may be configured with + minimal changes from `zcl.json` (but it is different) + +### Installing zap and environment variables + +Matter scripts may need to invoke `zap-cli` (for code generation) or `zap` (to +start the UI tool). For this, scrips need to know where to find the commands. In +the following order, the scripts process these environment variables: + +- if `$ZAP_DEVELOPMENT_PATH` is set, code assumes you are running zap from + source. Use this if you develop zap. Zap has to be bootstrapped (generally + `npm ci` but check zap documentation for this. Some scripts have a + `--run-bootstrap` command line argument to do this for you) + +- if `$ZAP_INSTALL_PATH` is set, code assumes that `zap` or `zap-cli` is + available in the given path. This is generally an unpacked release. + +- otherwise, scripts will assume `zap`/`zap-cli` is in `$PATH` + +### Using a UI to edit `.zap` files + +Generally you need to invoke zap with appropriate zcl and generate arguments. +Most of code generation is app specific, so you generally want something of the +form +`--gen src/app/zap-templates/app-templates.json --zcl $ZCL_JSON_FILE $ZAP_FILE_TO_EDIT` + +Since this is tedious to type, the SDK provides a +`scripts/tools/zap/run_zaptool.sh` script to automate this: + +```bash +# Ensure zap is in $PATH or set $ZAP_INSTALL_PATH or $ZAP_DEVELOPMENT_PATH +./scripts/tools/zap/run_zaptool.sh examples/lighting-app/lighting-common/lighting-app.zap +``` + +### Human-readable code generation inputs (`*.matter`) + +`.zap` files are large json files that are generally not human readable. As a +result, the Matter SDK also keeps an equivalent `*.matter` file along side +`.zap` files that contain the same data as `.zap` files, targeted specifically +for matter: + +- They are designed to be human readable, looking like a IDL (think protobuf + or android `aidl`, thrift idl etc.) + +- We strive to make them contain only Matter-specific data (`.zap` files + contain more generic data and is designed to be ZigBee backwards compatible) + +Currently `.matter` files are generated from `.zap` files during the application +specific codegen. + +### `*.matter` parsing and codegen + +`*.matter` files are both human and machine readable. Code that can process +these files is available at `scripts/idl` and `scripts/codegen.py`. You can read +the [scripts/idl/README.md](../scripts/idl/README.md) for details of how things +work. + +`scripts/codegen.py` can generate various outputs based on an input `*.matter` +file. + +The split between `.zap` and `.matter` currently exists as an experiment of code +generation technologies. Currently `.matter`-based Python code generation: + +- has fewer third party dependencies than `zap`, which installs a significant + number of `npm` packages. +- runs significantly faster than zap +- offers more flexible code generation (can generate multiple files per + cluster for example, without which some compiles would run out of RAM on + large compilations) +- has a more flexible templating language +- has human readable (and potentially editable) input +- is more easily provable deterministic (`zap` uses an underlying sqlite + database and some legacy assumptions from zigbee have historically caused + non-determinism) +- uses a synchronous processing model which is potentially easier to develop + for +- has lower complexity, is unit tested and uses typing extensively + +Ideally, the project would be to have a single code generation method in the +long term that has all the benefits and none of the drawbacks. We are not there +yet, however we likely want: + +- Flexible codegen (we will need to split output by clusters or other rules) +- Human-readable inputs that enable code reviews and audits +- Rules that a script can validate based on CSA data model (ensure mandatory + attribute settings are followed, ensure proper device type adherence, ensure + correct cluster and data type definitions) +- Easy to maintain and develop for chosen languages/templates/codegen in + general + +## Code generation outputs and templates + +Code that is generated: + +- **Application-specific**: + + - ZAP generation is based on `.zap` files in `examples/` and generates + server-side processing data: what cluster callbacks to set up, what RAM + to reserve for attribute storage etc. + + - `Codegen.py` will also generate a subset of application-specific files + +- **Automated tests**: embedded client-side tools (`chip-tool` and + `darwin-framework-tool`) generate test-definition data. Each use their own + `examples/${TOOL}/templates/tests/templates.json` to drive what gets + generated. + +- **Controller clusters** target: the file + `src/controller/data_model/controller-clusters.zap` contains a set of + cluster selections to which all applications would potentially have access. + These are generally used as `all clusters selection` and the intent is to + allow any application to access any cluster as a `client side`. + + Client/controllers will codegen based on this, like **tools**, **tests**, + **java**, **python** etc. + +## Running codegen + +### ZAP file generation + +Generating all possible code (all categories above) using zap tool can be done +via: + +```bash +./scripts/tools/zap_regen_all.py +``` + +This can be slow (several minutes). The regen tool allows selection of only +tests so that yaml test development goes faster. + +```bash +./scripts/tools/zap_regen_all.py --type tests +./scripts/tools/zap_regen_all.py --type tests --tests chip-tool +``` + +Additionally, individual code regeneration can be done using +`./scripts/tools/zap/generate.py`: + +```bash +/scripts/tools/zap/generate.py \ + examples/bridge-app/bridge-common/bridge-app.zap \ + -o zzz_generated/bridge-app/zap-generated +``` + +### `*.matter` code generation + +`*.matter` code generation can be done either at compile time or it can use +pre-generated output. + +Rules for how `codegen.py` is invoked and how includes/sources are set are +defined at: + +- `src/app/chip_data_model.cmake` +- `src/app/chip_data_model.gni` + +Additionally, `build/chip/esp32/esp32_codegen.cmake` adds processing support for +the 2-pass cmake builds used by the Espressif `idf.py` build system. + +## Pre-generation + +Code pre-generation can be used: + +- when compile-time code generation is not desirable. This may be for + importing into build systems that do not have the pre-requisites to run code + generation at build time or to save the code generation time at the expense + of running code generation for every possible zap/generation type +- To check changes in generated code across versions, beyond the comparisons + of golden image tests in `scripts/idl/tests` + +The script to trigger code pre-generation is `scripts/code_pregenerate.py` and +requires the pre-generation output directory as an argument + +```bash +scripts/code_pregenerate.py ${OUTPUT_DIRECTORY:-./zzz_pregenerated/} +``` diff --git a/docs/guides/BUILDING.md b/docs/guides/BUILDING.md index 10fe92958e4b55..fa5c8817416979 100644 --- a/docs/guides/BUILDING.md +++ b/docs/guides/BUILDING.md @@ -128,6 +128,35 @@ update_config=1 Finally, reboot your RPi. +## Installing ZAP + +`zap-cli` is already installed in pre-built docker images for chip-build, such +as +[chip-build-vscode](https://hub.docker.com/r/connectedhomeip/chip-build-vscode). + +Zap generation and tooling relies on `zap-cli` being available on the current +system. You can install it from the zap project +[Releases](https://github.com/project-chip/zap/releases). + +You should install a compatible release version, generally checking against the +release set in +[integrations/docker/images/chip-build/Dockerfile](../../../integrations/docker/images/chip-build/Dockerfile). + +On linux, installation from `zap-linux.zip` is recommended as it pulls fewer +dependencies than the `.deb` package. + +### Which ZAP to use + +ZAP scripting uses the following detection, in order: + +- `$ZAP_DEVELOPMENT_PATH` to point to a zap checkout. Use this if you are + developing zap locally and would like to run zap with your changes + +- `$ZAP_INSTALL_PATH` to point to where `zap-linux.zip`/`zap-mac.zip` was + unpacked. This allows you to not need to place zap/zap-cli in `$PATH` + +- Otherwise scripts assume `zap-cli` or `zap` is available in `$PATH` + ## Prepare for building Before running any other build command, the `scripts/activate.sh` environment diff --git a/docs/guides/esp32/build_app_and_commission.md b/docs/guides/esp32/build_app_and_commission.md index 8afa3eeada1a0c..db7ee6ebc30604 100644 --- a/docs/guides/esp32/build_app_and_commission.md +++ b/docs/guides/esp32/build_app_and_commission.md @@ -20,7 +20,7 @@ the esp32 application. ## Supported target chips -All the CHIP demo application is intended to work on: the +All the Matter demo application is intended to work on: the [ESP32-DevKitC](https://www.espressif.com/en/products/hardware/esp32-devkitc/overview), the [ESP32-WROVER-KIT_V4.1](https://www.espressif.com/en/products/hardware/esp-wrover-kit/overview), @@ -51,7 +51,7 @@ functionality can still work fine. $ source export.sh ``` -- CHIP +- Matter Before running any other build command, the scripts/activate.sh environment setup script should be sourced at the top level. This script set up a Python @@ -79,10 +79,10 @@ functionality can still work fine. $ cd examples//esp32 ``` -- Set the chip target to build +- Set the Matter target to build ``` - $ idf.py set-target (CHIP) + $ idf.py set-target (Matter) ``` All the example applications supports target chips: esp32, esp32s3, esp32c3 diff --git a/docs/guides/esp32/setup_idf_chip.md b/docs/guides/esp32/setup_idf_chip.md index 9ea0a7d50c65da..4b1938e64c2d7f 100644 --- a/docs/guides/esp32/setup_idf_chip.md +++ b/docs/guides/esp32/setup_idf_chip.md @@ -1,6 +1,6 @@ -# Setup ESP-IDF and CHIP Environment +# Setup ESP-IDF and Matter Environment -Setting up IDF and CHIP environment is one time setup. +Setting up IDF and Matter environment is one time setup. ## Setup ESP-IDF (Espressif IoT Development Framework) @@ -50,7 +50,7 @@ step. $ ./install.sh ``` -## Setup CHIP environment +## Setup Matter environment ### Install Prerequisites @@ -77,5 +77,5 @@ source scripts/bootstrap.sh --- -Once IDF and CHIP environment is set up, head over to +Once IDF and Matter environment is set up, head over to [application building and commissioning guide](build_app_and_commission.md). diff --git a/docs/guides/images/CHIPTool_device_commissioned.jpg b/docs/guides/images/CHIPTool_device_commissioned.jpg deleted file mode 100644 index 85bbbdc2b8fefc..00000000000000 Binary files a/docs/guides/images/CHIPTool_device_commissioned.jpg and /dev/null differ diff --git a/docs/guides/images/CHIPTool_device_commissioned.png b/docs/guides/images/CHIPTool_device_commissioned.png new file mode 100644 index 00000000000000..8756b4dbf6b0ca Binary files /dev/null and b/docs/guides/images/CHIPTool_device_commissioned.png differ diff --git a/docs/guides/nrfconnect_android_commissioning.md b/docs/guides/nrfconnect_android_commissioning.md index 7bbc0e3e7aef21..21096da4d2bab6 100644 --- a/docs/guides/nrfconnect_android_commissioning.md +++ b/docs/guides/nrfconnect_android_commissioning.md @@ -1,13 +1,14 @@ # Commissioning nRF Connect Accessory using Android CHIPTool You can use [CHIPTool](android_building.md) for Android smartphones to -commission a Nordic Semiconductor device running an nRF Connect platform example -onto a Matter-enabled Thread network. +commission a Nordic Semiconductor's development kit programmed with a Matter +example for the nRF Connect platform into a Matter fabric. -This guide references the nRF52840 DK and the door lock example application -based on the nRF Connect platform, but the instructions are also valid for the -nRF Connect lighting example application and can be adapted to other platforms -and applications as well. +This guide references the nRF52840 DK and Matter nRF Connect Lighting Example +Application that communicates with other nodes over a Thread network, but the +instructions can be adapted to other platforms and applications. For instance, +some sections of this guide include steps for testing a Wi-Fi device, which are +adapted from the original Thread-based procedure.
@@ -30,8 +31,8 @@ The commissioning process is composed of the following main stages: 1. CHIPTool discovers a Matter accessory device over Bluetooth LE. 2. CHIPTool establishes a secure channel to the device over Bluetooth LE, and - sends Matter operational credentials and Thread provisioning data. -3. The accessory device joins a Matter-enabled Thread network. + sends Matter operational credentials and Thread or Wi-Fi credentials. +3. The accessory device joins the operational IPv6 network. CHIPTool uses both Bluetooth LE and the IPv6 connectivity. Bluetooth LE is used only during the commissioning phase. Afterwards, only the IPv6 connectivity @@ -41,13 +42,13 @@ commissioning process and CHIPTool must use DNS Service Discovery (DNS-SD) to learn or refresh the address before the controller initiates the IPv6-based communication. -Since a typical smartphone does not have a Thread radio built-in, extra effort -is needed to prepare the fully-fledged testing environment that includes a -Thread Border Router configured on a Raspberry Pi. +Since a typical smartphone does not have a Thread radio built-in, preparing the +fully-fledged testing environment for Matter over Thread requires a Thread +Border Router configured on a Raspberry Pi. The following diagram shows the connectivity between network components required -to allow communication between devices running the CHIPTool and Lock -applications: +to allow communication between devices running CHIPTool and Matter nRF Connect +Lighting Example Application: ![Matter nodes connectivity](./images/nrfconnect_android_connectivity.png) @@ -60,20 +61,27 @@ applications: You need the following hardware and software for commissioning the nRF Connect accessory using Android CHIPTool: -- Two nRF52840 DK (PCA10056) +- 1x smartphone with Android 8+ +- 1x Wi-Fi Access Point supporting IPv6 (without the IPv6 Router Advertisement + Guard enabled on the router) +- 1x nRF52840 DK (PCA10056) for running the example application. You can + replace this DK with another compatible device, such as the nRF5340 DK or + nRF7002 DK. nRF52840 DK and nRF5340 DK can be used to test Matter over + Thread, and nRF7002 DK can be used to test Matter over Wi-Fi. - - One nRF52840 DK is needed for running the - [OpenThread Radio Co-Processor](https://openthread.io/platforms/co-processor) - firmware. You can replace this DK with another compatible device, such - as the nRF52840 Dongle. - - One nRF52840 DK is needed for running the example application. You can - replace this DK with another compatible device, such as the nRF5340 DK. +- 1x nRF52840 DK for running the + [OpenThread Radio Co-Processor](https://openthread.io/platforms/co-processor) + firmware. You can replace this DK with another compatible device, such as + the nRF52840 Dongle. -- Smartphone compatible with Android 8.0 or later -- Raspberry Pi Model 3B+ or newer (along with an SD card with at least 8 GB of - memory) -- Wi-Fi Access Point supporting IPv6 (without the IPv6 Router Advertisement - Guard enabled on the router) + > _Note:_ This piece of hardware is only needed if you're testing a Thread + > device. Skip it if the tested device operates in a Wi-Fi network. + +- 1x Raspberry Pi Model 3B+ or newer (along with an SD card with at least 8 GB + of memory) + + > _Note:_ This piece of hardware is only needed if you're testing a Thread + > device. Skip it if the tested device operates in a Wi-Fi network.
@@ -81,10 +89,15 @@ accessory using Android CHIPTool: ## Setting up Thread Border Router +> _Note:_ This step is only needed if you're testing a Thread device. Skip it if +> the tested device operates in a Wi-Fi network. + Follow the [OpenThread Border Router](openthread_border_router_pi.md) article to set up OpenThread Border Router on the Raspberry Pi, with either the nRF52840 DK or the nRF52840 Dongle acting as the [OpenThread Radio Co-Processor](https://openthread.io/platforms/co-processor). +During the setup, make sure that the Raspberry Pi is connected to your Wi-Fi +Access Point.
@@ -94,8 +107,8 @@ or the nRF52840 Dongle acting as the Build and program the example application onto your compatible device. -For this guide, see the documentation for the door lock example application to -learn how to build and program the example onto an nRF52840 DK. +For this guide, see the documentation of Matter nRF Connect Lighting Example +Application to learn how to build and program the example onto an nRF52840 DK.
@@ -164,24 +177,24 @@ To prepare the accessory device for commissioning, complete the following steps: ## Commissioning accessory device -To commission the accessory device onto the Thread network created in the -[Setting up Thread Border Router](#setting-up-thread-border-router) section, -complete the following steps: - -1. Enable **Bluetooth** and **Location** services on your smartphone. -2. Connect the smartphone to the same Wi-Fi network as the Raspberry Pi which - runs OpenThread Border Router. -3. Open the CHIPTool application on your smartphone. -4. Tap the **PROVISION CHIP DEVICE WITH THREAD** button and scan the - commissioning QR code. Several notifications will appear, informing you of - commissioning progress with scanning, connection, and pairing. At the end of - this process, the Thread network settings screen appears. -5. In the Thread network settings screen, use the default settings and tap the - **SAVE NETWORK** button to send a Thread provisioning message to the - accessory device. - -You will see the "Network provisioning completed" message when the accessory -device successfully joins the Thread network. +To commission the accessory device into the Matter fabric, complete the +following steps: + +1. Enable **Bluetooth** and **Location** services on your smartphone. +2. Connect the smartphone to your Wi-Fi Access Point. +3. Open the CHIPTool application on your smartphone. +4. Depending on your testing scenario, tap one of the following buttons and + scan the commissioning QR code: + + - **PROVISION CHIP DEVICE WITH THREAD** for Matter over Thread + - **PROVISION CHIP DEVICE WITH WI-FI** for Matter over Wi-Fi + + The network credentials screen appears. + +5. In the network credentials screen, specify parameters of network and tap the + **SAVE NETWORK** button. Several notifications appear, informing you of the + progress of scanning, connecting, and pairing with the device. At the end of + this process, the application returns to the main menu.
@@ -195,21 +208,16 @@ Check the IPv6 connectivity with the device using the following steps: 1. Tap **LIGHT ON/OFF & LEVEL CLUSTER**. The following screen appears: - ![CHIPTool device control screen](./images/CHIPTool_device_commissioned.jpg) + ![CHIPTool device control screen](./images/CHIPTool_device_commissioned.png) The two textboxes at the top contain **Fabric ID** and **Node ID** of the last commissioned device. -2. Tap **UPDATE ADDRESS** to learn or refresh the IPv6 address of the device. - CHIPTool will use a built-in DNS-SD client to resolve **Fabric ID** and - **Node ID** of the device to its IPv6 address. The result of the operation, - be it the address or an error message, will be displayed at the bottom of the - screen. -3. Tap the following buttons to change the lock state of the nRF Connect door - lock example application referenced in this guide: +2. Tap the following buttons to change the lighting state of the Matter nRF + Connect Lighting Example Application referenced in this guide: - - **ON** and **OFF** buttons lock and unlock the door, respectively. - - **TOGGLE** changes the lock state to the opposite. + - **ON** and **OFF** buttons turn on and off the light, respectively. + - **TOGGLE** changes the lighting state to the opposite. -The **LED 2** on the device turns on or off based on the changes of the lock +The **LED 2** on the device turns on or off based on the changes of the lighting state. diff --git a/docs/guides/nrfconnect_factory_data_configuration.md b/docs/guides/nrfconnect_factory_data_configuration.md index 3dc71cd58ddd92..071fc69ed9a02e 100644 --- a/docs/guides/nrfconnect_factory_data_configuration.md +++ b/docs/guides/nrfconnect_factory_data_configuration.md @@ -225,12 +225,9 @@ $ python scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py -h - Automatic: ``` - --passcode --spake2p_path + --passcode ``` - > Note: To generate new SPAKE2+ verifier you need `spake2p` executable. See - > the note at the end of this section to learn how to get it. - - Manual: ``` @@ -320,7 +317,6 @@ $ python scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py \ --discriminator 0xF00 \ --generate_rd_uid \ --passcode 20202021 \ ---spake2p_path "src/tools/spake2p/out/spake2p" \ --out "build.json" \ --schema "scripts/tools/nrfconnect/nrfconnect_factory_data.schema" ``` @@ -333,16 +329,6 @@ If the script finishes successfully, go to the location you provided with the `-o` argument. Use the JSON file you find there when [generating the factory data partition](#generating_factory_data_partition). -> Note: Generating the SPAKE2+ verifier is optional and requires providing a -> path to the `spake2p` executable. To get it, complete the following steps: -> -> 1. Navigate to the `connectedhomeip` root directory. -> 2. In a terminal, run the command: -> `cd src/tools/spake2p && gn gen out && ninja -C out spake2p` to build the -> executable. -> 3. Add the `connectedhomeip/src/tools/spake2p/out/spake2p` path as an -> argument of `--spake2p_path` for the Python script. - > Note: Generating new certificates is optional if default vendor and product > IDs are used and requires providing a path to the `chip-cert` executable. To > get it, complete the following steps: diff --git a/docs/guides/python_chip_controller_building.md b/docs/guides/python_chip_controller_building.md index 693dacf3732055..2d6ad8278e7928 100644 --- a/docs/guides/python_chip_controller_building.md +++ b/docs/guides/python_chip_controller_building.md @@ -1,3 +1,9 @@ +# Deprecation notice + +chip-device-ctrl is no longer maintained and should not be used. + +Matter-repl is the current python controller implementation. + # Working with Python CHIP Controller The Python CHIP Controller is a tool that allows to commission a Matter device @@ -624,10 +630,10 @@ ZCL cluster commands. ```python # devCtrl.WriteAttribute(, [(, Clusters..Attributes.(value=))]) # e.g. -await devCtrl.WriteAttribute(1, [(1, Clusters.TestCluster.Attributes.Int8u(value=1))]) -await devCtrl.WriteAttribute(1, [(1, Clusters.TestCluster.Attributes.Boolean(value=True))]) -await devCtrl.WriteAttribute(1, [(1, Clusters.TestCluster.Attributes.OctetString(value=b'123123\x00'))]) -await devCtrl.WriteAttribute(1, [(1, Clusters.TestCluster.Attributes.CharString(value='233233'))]) +await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.Int8u(value=1))]) +await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.Boolean(value=True))]) +await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.OctetString(value=b'123123\x00'))]) +await devCtrl.WriteAttribute(1, [(1, Clusters.UnitTesting.Attributes.CharString(value='233233'))]) ``` ### `zclsubscribe ` diff --git a/docs/guides/repl/Matter_Basic_Interactions.ipynb b/docs/guides/repl/Matter_Basic_Interactions.ipynb index fe2e36630e4a3c..0693f197cdc8b9 100644 --- a/docs/guides/repl/Matter_Basic_Interactions.ipynb +++ b/docs/guides/repl/Matter_Basic_Interactions.ipynb @@ -98,7 +98,7 @@ "\n", "### Namespaces\n", "\n", - "Objects in clusters are organized into namespaces. All clusters can be found under the `Clusters` namespace, with the appropriate cluster in upper camel case within that. (e.g `Clusters.TestCluster`).\n", + "Objects in clusters are organized into namespaces. All clusters can be found under the `Clusters` namespace, with the appropriate cluster in upper camel case within that. (e.g `Clusters.UnitTesting`).\n", "\n", "Within that, `Commands`, `Structs` and `Attributes` delimit the respective types in the cluster.\n", "\n", @@ -146,10 +146,10 @@ } ], "source": [ - "v = Clusters.TestCluster.Structs.SimpleStruct()\n", + "v = Clusters.UnitTesting.Structs.SimpleStruct()\n", "v.a = 20\n", "v.b = True\n", - "v.c = Clusters.TestCluster.Enums.SimpleEnum.kValueA\n", + "v.c = Clusters.UnitTesting.Enums.SimpleEnum.kValueA\n", "v.d = b'1234'\n", "v.e = 30\n", "v.g = 23.234\n", @@ -194,7 +194,7 @@ } ], "source": [ - "Clusters.TestCluster.Commands.TestAddArguments()" + "Clusters.UnitTesting.Commands.TestAddArguments()" ] }, { @@ -214,7 +214,7 @@ { "data": { "text/html": [ - "
╭──────── <class 'chip.clusters.Objects.TestCluster.Commands.TestAddArguments'> ─────────╮\n",
+       "
╭──────── <class 'chip.clusters.Objects.UnitTesting.Commands.TestAddArguments'> ─────────╮\n",
        " def TestCluster.Commands.TestAddArguments(arg1: 'uint' = 0, arg2: 'uint' = 0) -> None: \n",
        "                                                                                        \n",
        " TestAddArguments(arg1: 'uint' = 0, arg2: 'uint' = 0)                                   \n",
@@ -246,7 +246,7 @@
        "
\n" ], "text/plain": [ - "\u001b[34m╭─\u001b[0m\u001b[34m─────── \u001b[0m\u001b[1;34m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Commands.TestAddArguments'\u001b[0m\u001b[1;34m>\u001b[0m\u001b[34m ────────\u001b[0m\u001b[34m─╮\u001b[0m\n", + "\u001b[34m╭─\u001b[0m\u001b[34m─────── \u001b[0m\u001b[1;34m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Commands.TestAddArguments'\u001b[0m\u001b[1;34m>\u001b[0m\u001b[34m ────────\u001b[0m\u001b[34m─╮\u001b[0m\n", "\u001b[34m│\u001b[0m \u001b[3;96mdef \u001b[0m\u001b[1;31mTestCluster.Commands.TestAddArguments\u001b[0m\u001b[1m(\u001b[0marg1: \u001b[32m'uint'\u001b[0m = \u001b[1;36m0\u001b[0m, arg2: \u001b[32m'uint'\u001b[0m = \u001b[1;36m0\u001b[0m\u001b[1m)\u001b[0m -> \u001b[3;35mNone\u001b[0m: \u001b[34m│\u001b[0m\n", "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", "\u001b[34m│\u001b[0m \u001b[1;35mTestAddArguments\u001b[0m\u001b[1;36m(\u001b[0m\u001b[36marg1: \u001b[0m\u001b[32m'uint'\u001b[0m\u001b[36m = \u001b[0m\u001b[1;36m0\u001b[0m\u001b[36m, arg2: \u001b[0m\u001b[32m'uint'\u001b[0m\u001b[36m = \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;36m)\u001b[0m \u001b[34m│\u001b[0m\n", @@ -282,7 +282,7 @@ } ], "source": [ - "matterhelp(Clusters.TestCluster.Commands.TestAddArguments)" + "matterhelp(Clusters.UnitTesting.Commands.TestAddArguments)" ] }, { @@ -346,7 +346,7 @@ } ], "source": [ - "a = Clusters.TestCluster.Structs.NullablesAndOptionalsStruct()\n", + "a = Clusters.UnitTesting.Structs.NullablesAndOptionalsStruct()\n", "a.nullableInt = Clusters.Types.NullValue\n", "a" ] @@ -436,7 +436,7 @@ } ], "source": [ - "Clusters.TestCluster.Structs.SimpleStruct()" + "Clusters.UnitTesting.Structs.SimpleStruct()" ] }, { @@ -864,7 +864,7 @@ } ], "source": [ - "await devCtrl.SendCommand(2, 1, Clusters.TestCluster.Commands.TestListInt8UReverseRequest([1, 3, 5, 7]))" + "await devCtrl.SendCommand(2, 1, Clusters.UnitTesting.Commands.TestListInt8UReverseRequest([1, 3, 5, 7]))" ] }, { @@ -899,8 +899,8 @@ "
\n",
        "{\n",
        "1: {\n",
-       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0\n",
+       "│   │   <class 'chip.clusters.Objects.UnitTesting'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int16u'>: 0\n",
        "│   │   }\n",
        "}\n",
        "}\n",
@@ -910,8 +910,8 @@
        "\n",
        "\u001b[1m{\u001b[0m\n",
        "\u001b[2;32m│   \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n",
-       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n",
        "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m\n",
        "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m\n",
        "\u001b[1m}\u001b[0m\n"
@@ -922,7 +922,7 @@
     }
    ],
    "source": [
-    "a = await devCtrl.ReadAttribute(2, [Clusters.TestCluster.Attributes.Int16u])\n",
+    "a = await devCtrl.ReadAttribute(2, [Clusters.UnitTesting.Attributes.Int16u])\n",
     "a"
    ]
   },
@@ -937,14 +937,14 @@
       "text/html": [
        "
\n",
        "{\n",
-       "<class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0\n",
+       "<class 'chip.clusters.Objects.UnitTesting.Attributes.Int16u'>: 0\n",
        "}\n",
        "
\n" ], "text/plain": [ "\n", "\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n", "\u001b[1m}\u001b[0m\n" ] }, @@ -953,7 +953,7 @@ } ], "source": [ - "a[1][Clusters.TestCluster]" + "a[1][Clusters.UnitTesting]" ] }, { @@ -977,7 +977,7 @@ } ], "source": [ - "a[1][Clusters.TestCluster][Clusters.TestCluster.Attributes.Int16u]" + "a[1][Clusters.UnitTesting][Clusters.UnitTesting.Attributes.Int16u]" ] }, { @@ -1002,9 +1002,9 @@ "
\n",
        "{\n",
        "1: {\n",
-       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Boolean'>: False,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0\n",
+       "│   │   <class 'chip.clusters.Objects.UnitTesting'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Boolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int16u'>: 0\n",
        "│   │   }\n",
        "}\n",
        "}\n",
@@ -1014,9 +1014,9 @@
        "\n",
        "\u001b[1m{\u001b[0m\n",
        "\u001b[2;32m│   \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n",
-       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Boolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Boolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n",
        "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m\n",
        "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m\n",
        "\u001b[1m}\u001b[0m\n"
@@ -1027,7 +1027,7 @@
     }
    ],
    "source": [
-    "await devCtrl.ReadAttribute(2, [Clusters.TestCluster.Attributes.Int16u, Clusters.TestCluster.Attributes.Boolean])"
+    "await devCtrl.ReadAttribute(2, [Clusters.UnitTesting.Attributes.Int16u, Clusters.UnitTesting.Attributes.Boolean])"
    ]
   },
   {
@@ -1305,8 +1305,8 @@
      "text": [
       "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 0, Attribute = , got IM Error: InteractionModelError: UnsupportedRead (0x8f)\n",
       "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: UnsupportedRead (0x8f)\n",
-      "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: InvalidDataType (0x8d)\n",
-      "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: Failure (0x1)\n"
+      "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: InvalidDataType (0x8d)\n",
+      "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: Failure (0x1)\n"
      ]
     },
     {
@@ -2122,46 +2122,46 @@
        "│   │   <class 'chip.clusters.Objects.AccountLogin'>: {\n",
        "│   │   │   <class 'chip.clusters.Objects.AccountLogin.Attributes.ClusterRevision'>: 1\n",
        "│   │   },\n",
-       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Boolean'>: False,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap8'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap16'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap32'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap64'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int8u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int24u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int32u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int40u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int48u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int56u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int64u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int8s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int24s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int32s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int40s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int48s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int56s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int64s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Enum8'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Enum16'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.FloatSingle'>: 0.0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.FloatDouble'>: 0.0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.OctetString'>: b'',\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListInt8u'>: [\n",
+       "│   │   <class 'chip.clusters.Objects.UnitTesting'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Boolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Bitmap8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Bitmap16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Bitmap32'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Bitmap64'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int8u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int16u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int24u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int32u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int40u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int48u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int56u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int64u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int8s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int16s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int24s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int32s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int40s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int48s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int56s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int64s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Enum8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Enum16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.FloatSingle'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.FloatDouble'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.OctetString'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ListInt8u'>: [\n",
        "│   │   │   │   0,\n",
        "│   │   │   │   0,\n",
        "│   │   │   │   0,\n",
        "│   │   │   │   0\n",
        "│   │   │   ],\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListOctetString'>: [\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ListOctetString'>: [\n",
        "│   │   │   │   b'',\n",
        "│   │   │   │   b'',\n",
        "│   │   │   │   b'',\n",
        "│   │   │   │   b''\n",
        "│   │   │   ],\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListStructOctetString'>: [\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ListStructOctetString'>: [\n",
        "│   │   │   │   TestListStructOctet(\n",
        "│   │   │   │   │   fabricIndex=0,\n",
        "│   │   │   │   │   operationalCert=b''\n",
@@ -2179,13 +2179,13 @@
        "│   │   │   │   │   operationalCert=b''\n",
        "│   │   │   │   )\n",
        "│   │   │   ],\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.LongOctetString'>: b'',\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.CharString'>: '',\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.LongCharString'>: '',\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.EpochUs'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.EpochS'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.VendorId'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListNullablesAndOptionalsStruct'>: [\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.LongOctetString'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.CharString'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.LongCharString'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.EpochUs'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.EpochS'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.VendorId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ListNullablesAndOptionalsStruct'>: [\n",
        "│   │   │   │   NullablesAndOptionalsStruct(\n",
        "│   │   │   │   │   nullableInt=Null,\n",
        "│   │   │   │   │   optionalInt=None,\n",
@@ -2201,8 +2201,8 @@
        "│   │   │   │   │   nullableOptionalList=None\n",
        "│   │   │   │   )\n",
        "│   │   │   ],\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.EnumAttr'>: <SimpleEnum.kUnspecified: 0>,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.StructAttr'>: SimpleStruct(\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.EnumAttr'>: <SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.StructAttr'>: SimpleStruct(\n",
        "│   │   │   │   a=0,\n",
        "│   │   │   │   b=False,\n",
        "│   │   │   │   c=<SimpleEnum.kUnspecified: 0>,\n",
@@ -2212,64 +2212,64 @@
        "│   │   │   │   g=0.0,\n",
        "│   │   │   │   h=0.0\n",
        "│   │   │   ),\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8u'>: 70,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8s'>: -20,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16u'>: 200,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16s'>: -100,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListLongOctetString'>: [\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt8u'>: 70,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt8s'>: -20,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt16u'>: 200,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt16s'>: -100,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ListLongOctetString'>: [\n",
        "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',\n",
        "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',\n",
        "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',\n",
        "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\n",
        "│   │   │   ],\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListFabricScoped'>: [\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ListFabricScoped'>: [\n",
        "│   │   │   │   TestFabricScoped(\n",
        "│   │   │   │   │   fabricIndex=1\n",
        "│   │   │   │   )\n",
        "│   │   │   ],\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.TimedWriteBoolean'>: False,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.GeneralErrorBoolean'>: ValueDecodeFailure(\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.TimedWriteBoolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.GeneralErrorBoolean'>: ValueDecodeFailure(\n",
        "│   │   │   │   TLVValue=None,\n",
        "│   │   │   │   Reason=InteractionModelError(<Status.InvalidDataType: 141>)\n",
        "│   │   │   ),\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ClusterErrorBoolean'>: ValueDecodeFailure(\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ClusterErrorBoolean'>: ValueDecodeFailure(\n",
        "│   │   │   │   TLVValue=None,\n",
        "│   │   │   │   Reason=InteractionModelError(<Status.Failure: 1>)\n",
        "│   │   │   ),\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBoolean'>: False,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap8'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap16'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap32'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap64'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt8u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt16u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt24u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt32u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt40u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt48u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt56u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt64u'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt8s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt16s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt24s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt32s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt40s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt48s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt56s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt64s'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableEnum8'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableEnum16'>: 0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableFloatSingle'>: 0.0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableFloatDouble'>: 0.0,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableOctetString'>: b'',\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableCharString'>: '',\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableEnumAttr'>: <SimpleEnum.kUnspecified: 0>,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableStruct'>: Null,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8u'>: 70,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8s'>: -20,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16u'>: 200,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16s'>: -100,\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ClusterRevision'>: 1\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableBoolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap32'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap64'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt8u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt16u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt24u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt32u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt40u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt48u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt56u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt64u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt8s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt16s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt24s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt32s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt40s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt48s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt56s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableInt64s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableEnum8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableEnum16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableFloatSingle'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableFloatDouble'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableOctetString'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableCharString'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableEnumAttr'>: <SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableStruct'>: Null,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt8u'>: 70,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt8s'>: -20,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt16u'>: 200,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt16s'>: -100,\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.ClusterRevision'>: 1\n",
        "│   │   },\n",
        "│   │   <class 'chip.clusters.Objects.ElectricalMeasurement'>: {\n",
        "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.MeasurementType'>: 0,\n",
@@ -3138,46 +3138,46 @@
        "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccountLogin'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccountLogin.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n",
        "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m,\n",
-       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Boolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap32'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap64'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int24u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int32u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int40u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int48u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int56u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int64u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int24s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int32s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int40s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int48s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int56s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int64s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Enum8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Enum16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.FloatSingle'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.FloatDouble'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.OctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Boolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Bitmap8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Bitmap16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Bitmap32'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Bitmap64'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int24u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int32u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int40u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int48u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int56u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int64u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int24s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int32s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int40s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int48s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int56s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int64s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Enum8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Enum16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.FloatSingle'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.FloatDouble'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.OctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ListInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1;36m0\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1;36m0\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1;36m0\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1;36m0\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ListOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb''\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb''\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb''\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb''\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListStructOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ListStructOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1;35mTestListStructOctet\u001b[0m\u001b[1m(\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[33moperationalCert\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m\n",
@@ -3195,13 +3195,13 @@
        "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[33moperationalCert\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1m)\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.LongOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.CharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.LongCharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.EpochUs'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.EpochS'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.VendorId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListNullablesAndOptionalsStruct'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.LongOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.CharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.LongCharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.EpochUs'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.EpochS'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.VendorId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ListNullablesAndOptionalsStruct'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1;35mNullablesAndOptionalsStruct\u001b[0m\u001b[1m(\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[33mnullableInt\u001b[0m=\u001b[35mNull\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[33moptionalInt\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
@@ -3217,8 +3217,8 @@
        "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[33mnullableOptionalList\u001b[0m=\u001b[3;35mNone\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1m)\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.EnumAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.StructAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.EnumAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.StructAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33ma\u001b[0m=\u001b[1;36m0\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mb\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mc\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n",
@@ -3228,64 +3228,64 @@
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mg\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mh\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m)\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m70\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-20\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m200\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-100\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListLongOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m70\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-20\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m200\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.RangeRestrictedInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-100\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ListLongOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListFabricScoped'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ListFabricScoped'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1;35mTestFabricScoped\u001b[0m\u001b[1m(\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   │   \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[1m)\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m]\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.TimedWriteBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.GeneralErrorBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.TimedWriteBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.GeneralErrorBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mTLVValue\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mReason\u001b[0m=\u001b[1;35mInteractionModelError\u001b[0m\u001b[1m(\u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mStatus.InvalidDataType:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m141\u001b[0m\u001b[1m>\u001b[0m\u001b[1m)\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m)\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ClusterErrorBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ClusterErrorBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mTLVValue\u001b[0m=\u001b[3;35mNone\u001b[0m,\n",
        "\u001b[2;32m│   │   │   │   \u001b[0m\u001b[33mReason\u001b[0m=\u001b[1;35mInteractionModelError\u001b[0m\u001b[1m(\u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mStatus.Failure:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m)\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m)\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap32'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap64'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt24u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt32u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt40u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt48u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt56u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt64u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt24s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt32s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt40s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt48s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt56s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt64s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableEnum8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableEnum16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableFloatSingle'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableFloatDouble'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableCharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableEnumAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableStruct'\u001b[0m\u001b[1m>\u001b[0m: Null,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m70\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-20\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m200\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-100\u001b[0m,\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap32'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableBitmap64'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt24u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt32u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt40u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt48u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt56u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt64u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt24s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt32s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt40s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt48s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt56s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableInt64s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableEnum8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableEnum16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableFloatSingle'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableFloatDouble'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableCharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableEnumAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableStruct'\u001b[0m\u001b[1m>\u001b[0m: Null,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m70\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-20\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m200\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.NullableRangeRestrictedInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-100\u001b[0m,\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n",
        "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m,\n",
        "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
        "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.MeasurementType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n",
@@ -3597,7 +3597,7 @@
    ],
    "source": [
     "# Force an event to get emitted.\n",
-    "await devCtrl.SendCommand(2, 1, Clusters.TestCluster.Commands.TestEmitTestEventRequest())\n",
+    "await devCtrl.SendCommand(2, 1, Clusters.UnitTesting.Commands.TestEmitTestEventRequest())\n",
     "\n",
     "await devCtrl.ReadEvent(2, [('*')])"
    ]
@@ -4075,7 +4075,7 @@
     }
    ],
    "source": [
-    "await devCtrl.SendCommand(2, 1, Clusters.TestCluster.Commands.TestEmitTestEventRequest())\n",
+    "await devCtrl.SendCommand(2, 1, Clusters.UnitTesting.Commands.TestEmitTestEventRequest())\n",
     "time.sleep(3)"
    ]
   },
@@ -4140,7 +4140,7 @@
     }
    ],
    "source": [
-    "await devCtrl.WriteAttribute(2, [ (1, Clusters.TestCluster.Attributes.Int16u(2)) ])"
+    "await devCtrl.WriteAttribute(2, [ (1, Clusters.UnitTesting.Attributes.Int16u(2)) ])"
    ]
   },
   {
@@ -4155,8 +4155,8 @@
        "
\n",
        "{\n",
        "1: {\n",
-       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
-       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 2\n",
+       "│   │   <class 'chip.clusters.Objects.UnitTesting'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.UnitTesting.Attributes.Int16u'>: 2\n",
        "│   │   }\n",
        "}\n",
        "}\n",
@@ -4166,8 +4166,8 @@
        "\n",
        "\u001b[1m{\u001b[0m\n",
        "\u001b[2;32m│   \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n",
-       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
-       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n",
+       "\u001b[2;32m│   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n",
+       "\u001b[2;32m│   │   │   \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UnitTesting.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n",
        "\u001b[2;32m│   │   \u001b[0m\u001b[1m}\u001b[0m\n",
        "\u001b[2;32m│   \u001b[0m\u001b[1m}\u001b[0m\n",
        "\u001b[1m}\u001b[0m\n"
@@ -4178,7 +4178,7 @@
     }
    ],
    "source": [
-    "await devCtrl.ReadAttribute(2, [ (1, Clusters.TestCluster.Attributes.Int16u) ])"
+    "await devCtrl.ReadAttribute(2, [ (1, Clusters.UnitTesting.Attributes.Int16u) ])"
    ]
   }
  ],
diff --git a/docs/guides/repl/Matter_REPL_Intro.ipynb b/docs/guides/repl/Matter_REPL_Intro.ipynb
index 83cc3ad8efadec..2960cbac92cb1a 100644
--- a/docs/guides/repl/Matter_REPL_Intro.ipynb
+++ b/docs/guides/repl/Matter_REPL_Intro.ipynb
@@ -670,7 +670,7 @@
        "                                                                                           \n",
        "                                             E.g                                           \n",
        "                                                 (1,                                       \n",
-       "                                             Clusters.TestCluster.Attributes.XYZAttribute \n",
+       "                                             Clusters.UnitTesting.Attributes.XYZAttribute \n",
        "                                             -- Write 'hello' to the XYZ attribute on the  \n",
        "                                             test cluster to endpoint 1                    \n",
        "                          ZCLAttributeList = def ZCLAttributeList():                       \n",
@@ -893,7 +893,7 @@
        "\u001b[34m│\u001b[0m                                                                                           \u001b[34m│\u001b[0m\n",
        "\u001b[34m│\u001b[0m                                             \u001b[2mE.g\u001b[0m                                           \u001b[34m│\u001b[0m\n",
        "\u001b[34m│\u001b[0m                                             \u001b[2m    \u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m                                      \u001b[34m│\u001b[0m\n",
-       "\u001b[34m│\u001b[0m                                             \u001b[1;2;35mClusters.TestCluster.Attributes.XYZAttribute\u001b[0m\u001b[1;2m…\u001b[0m \u001b[34m│\u001b[0m\n",
+       "\u001b[34m│\u001b[0m                                             \u001b[1;2;35mClusters.UnitTesting.luster.Attributes.XYZAttribute\u001b[0m\u001b[1;2m…\u001b[0m \u001b[34m│\u001b[0m\n",
        "\u001b[34m│\u001b[0m                                             \u001b[2m-- Write \u001b[0m\u001b[2;32m'hello'\u001b[0m\u001b[2m to the XYZ attribute on the \u001b[0m \u001b[34m│\u001b[0m\n",
        "\u001b[34m│\u001b[0m                                             \u001b[2mtest cluster to endpoint \u001b[0m\u001b[1;2;36m1\u001b[0m                    \u001b[34m│\u001b[0m\n",
        "\u001b[34m│\u001b[0m                          \u001b[3;33mZCLAttributeList\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mZCLAttributeList\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m:                       \u001b[34m│\u001b[0m\n",
diff --git a/docs/style/coding/CODING_STYLE_GUIDE.adoc b/docs/style/coding/CODING_STYLE_GUIDE.adoc
index c04f22c8d1ac01..d6436523d657a6 100644
--- a/docs/style/coding/CODING_STYLE_GUIDE.adoc
+++ b/docs/style/coding/CODING_STYLE_GUIDE.adoc
@@ -154,7 +154,7 @@ leveraged through toolchain-compatibility preprocessor macros.
 CHIP strives to use the latest C++ functionality as long as existing compilers
 support such standards.
 
-C{plusplus}14 is considered pervasive enough to be used. As compilers start 
+C{plusplus}14 is considered pervasive enough to be used. As compilers start
 supporting standards such as C{plusplus}17, C{plusplus}20 and beyond,
 CHIP may follow suit.
 
@@ -354,7 +354,7 @@ static chipDEFINE_ALIGNED_VAR(sThreadAttributes, sizeof (pthread_attr_t), uint64
 
 #endif // USE_STRUCT_STORAGE
 
-int foobar(void)
+int foobar()
 {
     int              retval;
     int              status;
@@ -427,10 +427,10 @@ destructed after deinitialization.
 class ThreadAttributes
 {
 public:
-    ThreadAttributes(void) {};
-    ~ThreadAttributes(void) {};
+    ThreadAttributes() {};
+    ~ThreadAttributes() {};
 
-    operator pthread_attr_t *(void) { return &mAttributes; }
+    operator pthread_attr_t *() { return &mAttributes; }
 
 private:
     pthread_attr_t mAttributes;
@@ -444,7 +444,7 @@ extern void * foobar_entry(void *aArgument);
 
 static chipDEFINE_ALIGNED_VAR(sThreadAttributes, sizeof (ThreadAttributes), uint64_t);
 
-int foobar(void)
+int foobar()
 {
     int                retval = -1;
     int                status;
@@ -530,9 +530,9 @@ storage of objects from a static array of storage.
 class Foo
 {
 public:
-    Foo(void);
+    Foo();
     Foo(const Foo &inFoo);
-    ~Foo(void);
+    ~Foo();
 };
 
 // Global Variables
@@ -554,7 +554,7 @@ static void CreateFooAllocator(void *inStorage,
                               inDestroy);
 }
 
-static StaticAllocatorBitmap &GetFooAllocator(void)
+static StaticAllocatorBitmap &GetFooAllocator()
 {
     return *sFooAllocator;
 }
@@ -571,7 +571,7 @@ static void FooDestroy(AllocatorBase &inAllocator, void *inObject)
     return;
 }
 
-int Init(void)
+int Init()
 {
     static const size_t sFooCount = CHIP_FOO_COUNT;
     static chipAllocatorStaticBitmapStorageDefine(sFooStorage, Foo, sFooCount, uint32_t, sizeof (void *));
@@ -586,7 +586,7 @@ int Init(void)
     return retval;
 }
 
-Foo * FooAllocate(void)
+Foo * FooAllocate()
 {
     Foo *foo;
 
diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter
index 6d461163f67e90..4f87fd2c122da9 100644
--- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter
+++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter
@@ -300,6 +300,11 @@ server cluster LevelControl = 8 {
     kFrequency = 0x4;
   }
 
+  bitmap LevelControlOptions : BITMAP8 {
+    kExecuteIfOff = 0x1;
+    kCoupleColorTempToLevel = 0x2;
+  }
+
   readonly attribute nullable int8u currentLevel = 0;
   readonly attribute int16u remainingTime = 1;
   readonly attribute int8u minLevel = 2;
@@ -307,7 +312,7 @@ server cluster LevelControl = 8 {
   readonly attribute int16u currentFrequency = 4;
   readonly attribute int16u minFrequency = 5;
   readonly attribute int16u maxFrequency = 6;
-  attribute bitmap8 options = 15;
+  attribute LevelControlOptions options = 15;
   attribute int16u onOffTransitionTime = 16;
   attribute nullable int8u onLevel = 17;
   attribute nullable int16u onTransitionTime = 18;
@@ -320,55 +325,55 @@ server cluster LevelControl = 8 {
   request struct MoveToLevelRequest {
     INT8U level = 0;
     nullable INT16U transitionTime = 1;
-    BITMAP8 optionsMask = 2;
-    BITMAP8 optionsOverride = 3;
+    LevelControlOptions optionsMask = 2;
+    LevelControlOptions optionsOverride = 3;
   }
 
   request struct MoveRequest {
     MoveMode moveMode = 0;
     nullable INT8U rate = 1;
-    BITMAP8 optionsMask = 2;
-    BITMAP8 optionsOverride = 3;
+    LevelControlOptions optionsMask = 2;
+    LevelControlOptions optionsOverride = 3;
   }
 
   request struct StepRequest {
     StepMode stepMode = 0;
     INT8U stepSize = 1;
     nullable INT16U transitionTime = 2;
-    BITMAP8 optionsMask = 3;
-    BITMAP8 optionsOverride = 4;
+    LevelControlOptions optionsMask = 3;
+    LevelControlOptions optionsOverride = 4;
   }
 
   request struct StopRequest {
-    BITMAP8 optionsMask = 0;
-    BITMAP8 optionsOverride = 1;
+    LevelControlOptions optionsMask = 0;
+    LevelControlOptions optionsOverride = 1;
   }
 
   request struct MoveToLevelWithOnOffRequest {
     INT8U level = 0;
     nullable INT16U transitionTime = 1;
-    BITMAP8 optionsMask = 2;
-    BITMAP8 optionsOverride = 3;
+    LevelControlOptions optionsMask = 2;
+    LevelControlOptions optionsOverride = 3;
   }
 
   request struct MoveWithOnOffRequest {
     MoveMode moveMode = 0;
     nullable INT8U rate = 1;
-    BITMAP8 optionsMask = 2;
-    BITMAP8 optionsOverride = 3;
+    LevelControlOptions optionsMask = 2;
+    LevelControlOptions optionsOverride = 3;
   }
 
   request struct StepWithOnOffRequest {
     StepMode stepMode = 0;
     INT8U stepSize = 1;
     nullable INT16U transitionTime = 2;
-    BITMAP8 optionsMask = 3;
-    BITMAP8 optionsOverride = 4;
+    LevelControlOptions optionsMask = 3;
+    LevelControlOptions optionsOverride = 4;
   }
 
   request struct StopWithOnOffRequest {
-    BITMAP8 optionsMask = 0;
-    BITMAP8 optionsOverride = 1;
+    LevelControlOptions optionsMask = 0;
+    LevelControlOptions optionsOverride = 1;
   }
 
   command MoveToLevel(MoveToLevelRequest): DefaultSuccess = 0;
@@ -3528,7 +3533,7 @@ server cluster ElectricalMeasurement = 2820 {
   readonly attribute int16u clusterRevision = 65533;
 }
 
-server cluster TestCluster = 4294048773 {
+server cluster UnitTesting = 4294048773 {
   enum SimpleEnum : ENUM8 {
     kUnspecified = 0;
     kValueA = 1;
@@ -4705,7 +4710,7 @@ endpoint 1 {
     ram      attribute clusterRevision default = 3;
   }
 
-  server cluster TestCluster {
+  server cluster UnitTesting {
     ram      attribute boolean;
     ram      attribute bitmap8;
     ram      attribute bitmap16;
diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
index 99d72eeea360c9..186bc91f1c688e 100644
--- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
+++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
@@ -8055,7 +8055,7 @@
           ]
         },
         {
-          "name": "Test Cluster",
+          "name": "Unit Testing",
           "code": 4294048773,
           "mfgCode": null,
           "define": "TEST_CLUSTER",
@@ -8107,7 +8107,7 @@
           ]
         },
         {
-          "name": "Test Cluster",
+          "name": "Unit Testing",
           "code": 4294048773,
           "mfgCode": null,
           "define": "TEST_CLUSTER",
@@ -19159,7 +19159,7 @@
           ]
         },
         {
-          "name": "Test Cluster",
+          "name": "Unit Testing",
           "code": 4294048773,
           "mfgCode": null,
           "define": "TEST_CLUSTER",
@@ -19331,7 +19331,7 @@
           ]
         },
         {
-          "name": "Test Cluster",
+          "name": "Unit Testing",
           "code": 4294048773,
           "mfgCode": null,
           "define": "TEST_CLUSTER",
diff --git a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp
index ff5a7a771e4923..93e93c25a653dd 100644
--- a/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp
+++ b/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp
@@ -96,7 +96,7 @@ CHIP_ERROR ActionsAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attr
 }
 } // anonymous namespace
 
-void MatterActionsPluginServerInitCallback(void)
+void MatterActionsPluginServerInitCallback()
 {
     registerAttributeAccessOverride(&gAttrAccess);
 }
diff --git a/examples/all-clusters-app/ameba/README.md b/examples/all-clusters-app/ameba/README.md
index ddbdf66ecf9a9d..a710a2e5e006f9 100644
--- a/examples/all-clusters-app/ameba/README.md
+++ b/examples/all-clusters-app/ameba/README.md
@@ -14,7 +14,7 @@ control.
     -   [Cluster control](#cluster-control)
     -   [Running RPC Console](#running-rpc-console)
     -   [Running Matter Shell](#running-matter-shell)
-    -   [Binding and Controlling a Lighting Device](#binding-and-controlling-a-lighting-device)
+    -   [Binding and Controlling a Device](#binding-and-controlling-a-device)
 
 ---
 
@@ -137,28 +137,55 @@ to be On or Off.
 
 -   Open the USB-TTL serial port and type `help` to view the available commands
 
-## Binding and Controlling a Lighting Device
+-   To know what are the available subcommands are there, enter `switch` command
+    in the shell
 
--   This example shows how to bind a Switch Device to a Lighting Device and
+## Binding and Controlling a Device
+
+-   This example shows how to bind a Switch Device to a Controllee Device and
     control it through the Matter Shell. One binding client (Switch Device) and
-    one binding server (Lighting Device) is required.
+    one binding server (Controllee) is required.
 
--   Commission the switch (nodeID 1) and lighting device (nodeID 2) using
+-   Commission the switch (nodeID 1) and controllee device (nodeID 2) using
     chip-tool.
 
               $ ./chip-tool pairing ble-wifi 1   20202021 3840
               $ ./chip-tool pairing ble-wifi 2   20202021 3840
 
-*   After successful commissioning, configure the ACL in the lighting device to
-    allow access from switch device and chip-tool.
+-   After successful commissioning, configure the ACL in the controllee device
+    to allow access from switch device and chip-tool.
 
               $ ./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null },{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [1], "targets": null }]' 2 0
 
--   Bind the lighting device to the switch device.
+-   Bind the endpoint 1 OnOff cluster of the controllee device to the switch
+    device.
 
               $ ./chip-tool binding write binding '[{"fabricIndex": 1, "node":2, "endpoint":1, "cluster":6}]' 1 1
 
--   Control the lighting device through the switch device's Matter Shell
+-   Send OnOff command to the device through the switch device's Matter Shell
+
+    `switch onoff on`
+
+    `switch onoff off`
+
+*   You may also bind more than one cluster to the switch device. Below command
+    binds the Identify, OnOff, LevelControl, ColorControl and Thermostat
+    clusters to the switch device.
+
+              $ ./chip-tool binding write binding '[{"fabricIndex": 1, "node":2, "endpoint":1, "cluster":3}, {"fabricIndex": 1, "node":2, "endpoint":1, "cluster":6}, {"fabricIndex": 1, "node":2, "endpoint":1, "cluster":8}, {"fabricIndex": 1, "node":2, "endpoint":1, "cluster":768}, {"fabricIndex": 1, "node":2, "endpoint":1, "cluster":513}]' 1 1
+
+-   After binding the clusters, you may send these cluster commands to the
+    controllee device through the switch device's Matter Shell. Follow the
+    format shown in the description of the commands.
+
+    `switch onoff on`
+
+    `switch levelcontrol movetolevel 100 0 0 0`
+
+    `switch colorcontrol movetohue 100 0 0 0 0`
+
+    `switch thermostat SPRL 0 0`
+
+*   You may also request to read cluster attributes from Matter Shell
 
-              > switch onoff on
-              > switch onoff off
+    `switch  read `
diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake
index fc18f2fa9704cd..b174ade253b92f 100755
--- a/examples/all-clusters-app/ameba/chip_main.cmake
+++ b/examples/all-clusters-app/ameba/chip_main.cmake
@@ -149,7 +149,6 @@ endif (matter_enable_ota_requestor)
 list(
     APPEND ${list_chip_main_sources}
 
-    ${chip_dir}/zzz_generated/all-clusters-app/zap-generated/callback-stub.cpp
     ${chip_dir}/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp
 
     ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp
@@ -235,6 +234,7 @@ target_link_libraries(${chip_main} PUBLIC
     pw_hdlc
     pw_log
     pw_rpc.server
+    pw_sys_io
     pw_trace_tokenized
     pw_trace_tokenized.trace_buffer
     pw_trace_tokenized.rpc_service
@@ -256,6 +256,7 @@ list(
     -DUSE_ZAP_CONFIG
     -DCHIP_HAVE_CONFIG_H
     -DMBEDTLS_CONFIG_FILE=
+    -DCHIP_SHELL_MAX_TOKENS=11
 )
 
 if (matter_enable_persistentstorage_audit)
diff --git a/examples/all-clusters-app/ameba/main/BindingHandler.cpp b/examples/all-clusters-app/ameba/main/BindingHandler.cpp
index 29acdaae952896..64ccb619a2edf5 100644
--- a/examples/all-clusters-app/ameba/main/BindingHandler.cpp
+++ b/examples/all-clusters-app/ameba/main/BindingHandler.cpp
@@ -17,10 +17,15 @@
  */
 
 #include "BindingHandler.h"
-#include "app/CommandSender.h"
+#include "ColorControlCommands.h"
+#include "IdentifyCommand.h"
+#include "LevelControlCommands.h"
+#include "OnOffCommands.h"
+#include "ThermostatCommands.h"
 #include "app/clusters/bindings/BindingManager.h"
 #include "app/server/Server.h"
 #include "controller/InvokeInteraction.h"
+#include "controller/ReadInteraction.h"
 #include "platform/CHIPDeviceLayer.h"
 #include 
 #include 
@@ -40,95 +45,84 @@ using Shell::streamer_get;
 using Shell::streamer_printf;
 
 Engine sShellSwitchSubCommands;
-Engine sShellSwitchOnOffSubCommands;
-
 Engine sShellSwitchGroupsSubCommands;
-Engine sShellSwitchGroupsOnOffSubCommands;
-
 Engine sShellSwitchBindingSubCommands;
 #endif // defined(ENABLE_CHIP_SHELL)
 
 namespace {
-
-void ProcessOnOffUnicastBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding,
-                                       OperationalDeviceProxy * peer_device)
-{
-    auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) {
-        ChipLogProgress(NotSpecified, "OnOff command succeeds");
-    };
-
-    auto onFailure = [](CHIP_ERROR error) {
-        ChipLogError(NotSpecified, "OnOff command failed: %" CHIP_ERROR_FORMAT, error.Format());
-    };
-
-    VerifyOrDie(peer_device != nullptr && peer_device->ConnectionReady());
-    switch (commandId)
-    {
-    case Clusters::OnOff::Commands::Toggle::Id:
-        Clusters::OnOff::Commands::Toggle::Type toggleCommand;
-        Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
-                                         toggleCommand, onSuccess, onFailure);
-        break;
-
-    case Clusters::OnOff::Commands::On::Id:
-        Clusters::OnOff::Commands::On::Type onCommand;
-        Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
-                                         onCommand, onSuccess, onFailure);
-        break;
-
-    case Clusters::OnOff::Commands::Off::Id:
-        Clusters::OnOff::Commands::Off::Type offCommand;
-        Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote,
-                                         offCommand, onSuccess, onFailure);
-        break;
-    }
-}
-
-void ProcessOnOffGroupBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding)
-{
-    Messaging::ExchangeManager & exchangeMgr = Server::GetInstance().GetExchangeManager();
-
-    switch (commandId)
-    {
-    case Clusters::OnOff::Commands::Toggle::Id:
-        Clusters::OnOff::Commands::Toggle::Type toggleCommand;
-        Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, toggleCommand);
-        break;
-
-    case Clusters::OnOff::Commands::On::Id:
-        Clusters::OnOff::Commands::On::Type onCommand;
-        Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, onCommand);
-
-        break;
-
-    case Clusters::OnOff::Commands::Off::Id:
-        Clusters::OnOff::Commands::Off::Type offCommand;
-        Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, offCommand);
-        break;
-    }
-}
-
 void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, OperationalDeviceProxy * peer_device, void * context)
 {
     VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null"));
     BindingCommandData * data = static_cast(context);
 
-    if (binding.type == EMBER_MULTICAST_BINDING && data->isGroup)
+    if (data->isReadAttribute)
     {
-        switch (data->clusterId)
+        // It should always enter here if isReadAttribute is true
+        if (binding.type == EMBER_UNICAST_BINDING && !data->isGroup)
         {
-        case Clusters::OnOff::Id:
-            ProcessOnOffGroupBindingCommand(data->commandId, binding);
-            break;
+            switch (data->clusterId)
+            {
+            case Clusters::Identify::Id:
+                ProcessIdentifyUnicastBindingRead(data, binding, peer_device);
+                break;
+            case Clusters::OnOff::Id:
+                ProcessOnOffUnicastBindingRead(data, binding, peer_device);
+                break;
+            case Clusters::LevelControl::Id:
+                ProcessLevelControlUnicastBindingRead(data, binding, peer_device);
+                break;
+            case Clusters::ColorControl::Id:
+                ProcessColorControlUnicastBindingRead(data, binding, peer_device);
+                break;
+            case Clusters::Thermostat::Id:
+                ProcessThermostatUnicastBindingRead(data, binding, peer_device);
+                break;
+            }
         }
     }
-    else if (binding.type == EMBER_UNICAST_BINDING && !data->isGroup)
+    else
     {
-        switch (data->clusterId)
+        if (binding.type == EMBER_MULTICAST_BINDING && data->isGroup)
         {
-        case Clusters::OnOff::Id:
-            ProcessOnOffUnicastBindingCommand(data->commandId, binding, peer_device);
-            break;
+            switch (data->clusterId)
+            {
+            case Clusters::Identify::Id:
+                ProcessIdentifyGroupBindingCommand(data, binding);
+                break;
+            case Clusters::OnOff::Id:
+                ProcessOnOffGroupBindingCommand(data, binding);
+                break;
+            case Clusters::LevelControl::Id:
+                ProcessColorControlGroupBindingCommand(data, binding);
+                break;
+            case Clusters::ColorControl::Id:
+                ProcessColorControlGroupBindingCommand(data, binding);
+                break;
+            case Clusters::Thermostat::Id:
+                ProcessThermostatGroupBindingCommand(data, binding);
+                break;
+            }
+        }
+        else if (binding.type == EMBER_UNICAST_BINDING && !data->isGroup)
+        {
+            switch (data->clusterId)
+            {
+            case Clusters::Identify::Id:
+                ProcessIdentifyUnicastBindingCommand(data, binding, peer_device);
+                break;
+            case Clusters::OnOff::Id:
+                ProcessOnOffUnicastBindingCommand(data, binding, peer_device);
+                break;
+            case Clusters::LevelControl::Id:
+                ProcessLevelControlUnicastBindingCommand(data, binding, peer_device);
+                break;
+            case Clusters::ColorControl::Id:
+                ProcessColorControlUnicastBindingCommand(data, binding, peer_device);
+                break;
+            case Clusters::Thermostat::Id:
+                ProcessThermostatUnicastBindingCommand(data, binding, peer_device);
+                break;
+            }
         }
     }
 }
@@ -149,7 +143,7 @@ void InitBindingHandlerInternal(intptr_t arg)
     chip::BindingManager::GetInstance().RegisterBoundDeviceContextReleaseHandler(LightSwitchContextReleaseHandler);
 }
 
-#ifdef CONFIG_ENABLE_CHIP_SHELL
+#if CONFIG_ENABLE_CHIP_SHELL
 
 /********************************************************
  * Switch shell functions
@@ -171,56 +165,6 @@ CHIP_ERROR SwitchCommandHandler(int argc, char ** argv)
     return sShellSwitchSubCommands.ExecCommand(argc, argv);
 }
 
-/********************************************************
- * OnOff switch shell functions
- *********************************************************/
-
-CHIP_ERROR OnOffHelpHandler(int argc, char ** argv)
-{
-    sShellSwitchOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR OnOffSwitchCommandHandler(int argc, char ** argv)
-{
-    if (argc == 0)
-    {
-        return OnOffHelpHandler(argc, argv);
-    }
-
-    return sShellSwitchOnOffSubCommands.ExecCommand(argc, argv);
-}
-
-CHIP_ERROR OnSwitchCommandHandler(int argc, char ** argv)
-{
-    BindingCommandData * data = Platform::New();
-    data->commandId           = Clusters::OnOff::Commands::On::Id;
-    data->clusterId           = Clusters::OnOff::Id;
-
-    DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR OffSwitchCommandHandler(int argc, char ** argv)
-{
-    BindingCommandData * data = Platform::New();
-    data->commandId           = Clusters::OnOff::Commands::Off::Id;
-    data->clusterId           = Clusters::OnOff::Id;
-
-    DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR ToggleSwitchCommandHandler(int argc, char ** argv)
-{
-    BindingCommandData * data = Platform::New();
-    data->commandId           = Clusters::OnOff::Commands::Toggle::Id;
-    data->clusterId           = Clusters::OnOff::Id;
-
-    DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
-    return CHIP_NO_ERROR;
-}
-
 /********************************************************
  * bind switch shell functions
  *********************************************************/
@@ -292,59 +236,6 @@ CHIP_ERROR GroupsSwitchCommandHandler(int argc, char ** argv)
     return sShellSwitchGroupsSubCommands.ExecCommand(argc, argv);
 }
 
-/********************************************************
- * Groups OnOff switch shell functions
- *********************************************************/
-
-CHIP_ERROR GroupsOnOffHelpHandler(int argc, char ** argv)
-{
-    sShellSwitchGroupsOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr);
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR GroupsOnOffSwitchCommandHandler(int argc, char ** argv)
-{
-    if (argc == 0)
-    {
-        return GroupsOnOffHelpHandler(argc, argv);
-    }
-
-    return sShellSwitchGroupsOnOffSubCommands.ExecCommand(argc, argv);
-}
-
-CHIP_ERROR GroupOnSwitchCommandHandler(int argc, char ** argv)
-{
-    BindingCommandData * data = Platform::New();
-    data->commandId           = Clusters::OnOff::Commands::On::Id;
-    data->clusterId           = Clusters::OnOff::Id;
-    data->isGroup             = true;
-
-    DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR GroupOffSwitchCommandHandler(int argc, char ** argv)
-{
-    BindingCommandData * data = Platform::New();
-    data->commandId           = Clusters::OnOff::Commands::Off::Id;
-    data->clusterId           = Clusters::OnOff::Id;
-    data->isGroup             = true;
-
-    DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR GroupToggleSwitchCommandHandler(int argc, char ** argv)
-{
-    BindingCommandData * data = Platform::New();
-    data->commandId           = Clusters::OnOff::Commands::Toggle::Id;
-    data->clusterId           = Clusters::OnOff::Id;
-    data->isGroup             = true;
-
-    DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data));
-    return CHIP_NO_ERROR;
-}
-
 /**
  * @brief configures switch matter shell
  *
@@ -354,27 +245,332 @@ static void RegisterSwitchCommands()
 
     static const shell_command_t sSwitchSubCommands[] = {
         { &SwitchHelpHandler, "help", "Usage: switch " },
+        { &IdentifySwitchCommandHandler, "identify", " Usage: switch identify " },
         { &OnOffSwitchCommandHandler, "onoff", " Usage: switch onoff " },
+        { &LevelControlSwitchCommandHandler, "levelcontrol", " Usage: switch levlecontrol " },
+        { &ColorControlSwitchCommandHandler, "colorcontrol", " Usage: switch colorcontrol " },
+        { &ThermostatSwitchCommandHandler, "thermostat", " Usage: switch thermostat " },
         { &GroupsSwitchCommandHandler, "groups", "Usage: switch groups " },
         { &BindingSwitchCommandHandler, "binding", "Usage: switch binding " }
     };
 
+    static const shell_command_t sSwitchIdentifySubCommands[] = {
+        { &IdentifyHelpHandler, "help", "Usage: switch identify " },
+        { &IdentifyCommandHandler, "identify", "identify Usage: switch identify identify" },
+        { &TriggerEffectSwitchCommandHandler, "triggereffect", "triggereffect Usage: switch identify triggereffect" },
+        { &IdentifyRead, "read", "Usage : switch identify read " }
+    };
+
+    static const shell_command_t sSwitchIdentifyReadSubCommands[] = {
+        { &IdentifyReadHelpHandler, "help", "Usage : switch identify read " },
+        { &IdentifyReadAttributeList, "attlist", "Read attribute list" },
+        { &IdentifyReadIdentifyTime, "identifytime", "Read identifytime attribute" },
+        { &IdentifyReadIdentifyType, "identifytype", "Read identifytype attribute" },
+    };
+
     static const shell_command_t sSwitchOnOffSubCommands[] = {
-        { &OnOffHelpHandler, "help", "Usage : switch ononff " },
-        { &OnSwitchCommandHandler, "on", "Sends on command to bound lighting app" },
-        { &OffSwitchCommandHandler, "off", "Sends off command to bound lighting app" },
-        { &ToggleSwitchCommandHandler, "toggle", "Sends toggle command to bound lighting app" }
+        { &OnOffHelpHandler, "help", "Usage: switch ononff " },
+        { &OnSwitchCommandHandler, "on", "on Usage: switch onoff on" },
+        { &OffSwitchCommandHandler, "off", "off Usage: switch onoff off" },
+        { &ToggleSwitchCommandHandler, "toggle", "toggle Usage: switch onoff toggle" },
+        { &OffWithEffectSwitchCommandHandler, "offWE", "off-with-effect Usage: switch onoff offWE  " },
+        { &OnWithRecallGlobalSceneSwitchCommandHandler, "onWRGS", "on-with-recall-global-scene Usage: switch onoff onWRGS" },
+        { &OnWithTimedOffSwitchCommandHandler, "onWTO",
+          "on-with-timed-off Usage: switch onoff onWTO   " },
+        { &OnOffRead, "read", "Usage : switch onoff read " }
+    };
+
+    static const shell_command_t sSwitchOnOffReadSubCommands[] = {
+        { &OnOffReadHelpHandler, "help", "Usage : switch ononff read " },
+        { &OnOffReadAttributeList, "attlist", "Read attribute list" },
+        { &OnOffReadOnOff, "onoff", "Read onoff attribute" },
+        { &OnOffReadGlobalSceneControl, "GSC", "Read GlobalSceneControl attribute" },
+        { &OnOffReadOnTime, "ontime", "Read ontime attribute" },
+        { &OnOffReadOffWaitTime, "offwaittime", "Read offwaittime attribute" },
+        { &OnOffReadStartUpOnOff, "SOO", "Read startuponoff attribute" },
+    };
+
+    static const shell_command_t sSwitchLevelControlSubCommands[] = {
+        { &LevelControlHelpHandler, "help", "Usage: switch levelcontrol " },
+        { &MoveToLevelSwitchCommandHandler, "movetolevel",
+          "movetolevel Usage: switch levelcontrol movetolevel    " },
+        { &MoveSwitchCommandHandler, "move",
+          "move Usage: switch levelcontrol move    " },
+        { &StepSwitchCommandHandler, "step",
+          "step Usage: switch levelcontrol step     " },
+        { &StopSwitchCommandHandler, "stop", "step Usage: switch levelcontrol stop  " },
+        { &MoveToLevelWithOnOffSwitchCommandHandler, "MTLWOO",
+          "movetolevelwithonoff Usage: switch levelcontrol MTLWOO    " },
+        { &MoveWithOnOffSwitchCommandHandler, "MWOO",
+          "movewithonoff Usage: switch levelcontrol MWOO    " },
+        { &StepWithOnOffSwitchCommandHandler, "stepWOO",
+          "stepwithonoff Usage: switch levelcontrol stepWOO     "
+          "" },
+        { &StopWithOnOffSwitchCommandHandler, "stopWOO",
+          "stopwithonoff Usage: switch levelcontrol stopWOO  " },
+        { &LevelControlRead, "read", "Usage : switch levelcontrol read " }
+    };
+
+    static const shell_command_t sSwitchLevelControlReadSubCommands[] = {
+        { &LevelControlReadHelpHandler, "help", "Usage : switch levelcontrol read " },
+        { &LevelControlReadAttributeList, "attlist", "Read attribute list" },
+        { &LevelControlReadCurrentLevel, "currentlevel", "Read currentlevel attribute" },
+        { &LevelControlReadRemainingTime, "remainingtime", "Read remainingtime attribute" },
+        { &LevelControlReadMinLevel, "minlevel", "Read minlevel attribute" },
+        { &LevelControlReadMaxLevel, "maxlevel", "Read maxlevel attribute" },
+        { &LevelControlReadCurrentFrequency, "currentfrequency", "Read currentfrequency attribute" },
+        { &LevelControlReadMinFrequency, "minfrequency", "Read minfrequency attribute" },
+        { &LevelControlReadMaxFrequency, "maxfrequency", "Read maxfrequency attribute" },
+        { &LevelControlReadOptions, "options", "Read options attribute" },
+        { &LevelControlReadOnOffTransitionTime, "OOTT", "Read onofftransitiontime attribute" },
+        { &LevelControlReadOnLevel, "onlevel", "Read onlevel attribute" },
+        { &LevelControlReadOnTransitionTime, "OnTT", "Read ontransitiontime attribute" },
+        { &LevelControlReadOffTransitionTime, "OffTT", "Read offtransitiontime attribute" },
+        { &LevelControlReadDefaultMoveRate, "DMR", "Read defaultmoverate attribute" },
+        { &LevelControlReadStartUpCurrentLevel, "SUCL", "Read startupcurrentlevel attribute" },
     };
 
-    static const shell_command_t sSwitchGroupsSubCommands[] = { { &GroupsHelpHandler, "help", "Usage: switch groups " },
-                                                                { &GroupsOnOffSwitchCommandHandler, "onoff",
-                                                                  "Usage: switch groups onoff " } };
+    static const shell_command_t sSwitchColorControlSubCommands[] = {
+        { &ColorControlHelpHandler, "help", "Usage: switch colorcontrol " },
+        { &MoveToHueCommandHandler, "movetohue",
+          "movetohue Usage: switch colorcontrol movetohue     " },
+        { &MoveHueCommandHandler, "movehue",
+          "movehue Usage: switch colorcontrol movehue    " },
+        { &StepHueCommandHandler, "stephue",
+          "stephue Usage: switch colorcontrol stephue     " },
+        { &MoveToSaturationCommandHandler, "movetosat",
+          "movetosaturation Usage: switch colorcontrol movetosat    " },
+        { &MoveSaturationCommandHandler, "movesat",
+          "movesaturation Usage: switch colorcontrol movesat    " },
+        { &StepSaturationCommandHandler, "stepsat",
+          "stepsaturation Usage: switch colorcontrol stepsat     "
+          "" },
+        { &MoveToHueAndSaturationCommandHandler, "movetoHS",
+          "movetohueandsaturation Usage: switch colorcontrol movetoHS     "
+          "" },
+        { &MoveToColorCommandHandler, "movetocolor",
+          "movetocolor Usage: switch colorcontrol movetocolor     " },
+        { &MoveColorCommandHandler, "movecolor",
+          "movecolor Usage: switch colorcontrol movecolor    " },
+        { &StepColorCommandHandler, "stepcolor",
+          "stepcolor Usage: switch colorcontrol stepcolor     " },
+        { &MoveToColorTemperatureCommandHandler, "movetoCT",
+          "movetocolortemperature Usage: switch colorcontrol movetoCT    "
+          "" },
+        { &EnhancedMoveToHueCommandHandler, "Emovetohue",
+          "enhancedmovetohue Usage: switch colorcontrol Emovetohue     "
+          "" },
+        { &EnhancedMoveHueCommandHandler, "Emovehue",
+          "enhancedmovehue Usage: switch colorcontrol Emovehue    " },
+        { &EnhancedStepHueCommandHandler, "Estephue",
+          "enhancedstephue Usage: switch colorcontrol Estephue     "
+          "" },
+        { &EnhancedMoveToHueAndSaturationCommandHandler, "EmovetoHS",
+          "enhancedmovetohueandsaturation Usage: switch colorcontrol EmovetoHS    "
+          " " },
+        { &ColorLoopSetCommandHandler, "colorloopset",
+          "colorloopset Usage: switch colorcontrol colorloopset