| # MATTER CHEF APP |
| |
| The purpose of the chef app is to to: |
| |
| 1. Increase the coverage of device types in Matter |
| 2. Provide a sample application that may have its data model easily configured. |
| |
| Chef uses the shell app a starting point, but processes the data model defined |
| on ZAP files during build time. This procedure is handled by its unified build |
| script: `chef.py`. |
| |
| When processing ZAP files as part of the build process, Chef places the |
| auto-generated zap artifacts under its `out` temporary folder. Chef uses |
| artifacts from `zzz_generated` for CI/CD. |
| |
| All device types available (.zap files) are found inside the `devices` folder. |
| |
| ## Building your first sample |
| |
| 1. Make sure you have the toolchain installed for your desired target. |
| 2. Run `chef.py` the first time to create a `config.yaml` configuration file. If |
| you already have SDK environment variables such as IDF_PATH (esp32) and |
| ZEPHYR_BASE (nrfconnect) it will use those values as default. |
| 3. Update your the SDK paths on `config.yaml`. TTY is the path used by the |
| platform to enumerate its device as a serial port. Typical values are: |
| |
| ``` |
| # ESP32 macOS |
| |
| TTY: /dev/tty.usbmodemXXXXXXX |
| |
| # ESP32 Linux |
| |
| TTY: /dev/ttyACM0 |
| |
| # NRFCONNECT macOS |
| |
| TTY: /dev/tty.usbserial-XXXXX |
| |
| # NRFCONNECT Linux |
| |
| TTY: /dev/ttyUSB0 |
| ``` |
| |
| 4. Run `$ chef.py -u` to update zap and the toolchain (on selected platforms). |
| 5. Run `$ chef.py -gzbf -t <platform> -d lighting`. This command will run the |
| ZAP GUI opening the `devices/lighting.zap` file and will allow editing. It |
| will then generate the zap artifacts, place them on the `zap-generated` |
| folder, run a build and flash the binary in your target. |
| 6. Run `chef.py -h` to see all available commands. |
| |
| ## Creating a new device type in your device library |
| |
| Follow guide in [NEW_CHEF_DEVICES.md](NEW_CHEF_DEVICES.md). |
| |
| ## Folder Structure and Guidelines |
| |
| - `<platform>`: build system and `main.cpp` file for every supported platform. |
| When porting a new platform, please minimize the source code in this folder, |
| favoring the `common` folder for code that is not platform related. |
| - `common`: contains code shared between different platforms. It may contain |
| source code that enables specific features such as `LightingManager` class |
| or `LockManager`, as long as the application dynamically identify the |
| presence of the relevant cluster configurations and it doesn't break the use |
| cases where chef is built without these clusters. |
| - `devices`: contains the data models that may be used with chef. As of Matter |
| 1.0 the data models are defined using .zap files. |
| - `out`: temporary folder used for placing ZAP generated artifacts. |
| - `sample_app_util`: guidelines and scripts for generating file names for new |
| device types committed to the `devices` folder. |
| - `config.yaml`: contains general configuration for the `chef.py` script. As |
| of Matter 1.0 this is used exclusively for toolchain and TTY interface |
| paths. |
| - `chef.py`: main script for generating samples. More info on its help |
| `chef.py -h`. |
| |
| ## General Linux Options |
| |
| When building chef for the Linux platform there are several options available at |
| runtime. These options are also available for many Linux samples. Do not |
| conflate these with chef options available at build time. |
| |
| Ex.: |
| |
| - --discriminator <discriminator>: A 12-bit unsigned integer match the value |
| which a device advertises during commissioning. |
| - --passcode <passcode>: A 27-bit unsigned integer, which serves as proof of |
| possession during commissioning. If not provided to compute a verifier, the |
| --spake2p-verifier-base64 must be provided. |
| - --secured-device-port <port>: A 16-bit unsigned integer specifying the |
| listen port to use for secure device messages (default is 5540). |
| - --KVS <filepath>: A file to store Key Value Store items. |
| |
| For a full list, call the generated linux binary with |
| |
| - -h, --help: Print this output and then exit. |
| |
| ## CI |
| |
| All CI jobs for chef can be found in `.github/workflows/chef.yaml`. |
| |
| These jobs use a platform-specific image with base `chip-build`. Such images |
| contain the toolchain for the respective platform under `/opt`. |
| |
| CI jobs call chef with the options `--ci -t $PLATFORM`. The `--ci` option will |
| execute builds for all devices specified in `ci_allow_list` defined in |
| `cicd_config.json` (so long as these devices are also in `/devices`) on the |
| specified platform. |
| |
| CI jobs also call the function `bundle_$PLATFORM` at the end of each example |
| build. This function should copy or move build output files from the build |
| output location into `_CD_STAGING_DIR`. Typically, the set of files touched is |
| the minimal set of files needed to flash a device. See the function |
| `bundle_esp32` for reference. |
| |
| ### Adding a platform |
| |
| First, implement a `bundle_$PLATFORM` function. |
| |
| Next, ensure that the examples in `ci_allow_list` build in a container using the |
| relevant platform image. You can simulate the workflow locally by mounting your |
| CHIP repo into a container and executing the CI command: |
| |
| ```shell |
| docker run -it --mount source=$(pwd),target=/workspace,type=bind ghcr.io/project-chip/chip-build-$PLATFORM:$VERSION |
| ``` |
| |
| In the container: |
| |
| ```shell |
| chown -R $(whoami) /workspace |
| cd /workspace |
| source ./scripts/bootstrap.sh |
| source ./scripts/activate.sh |
| ./examples/chef/chef.py --ci -t $PLATFORM |
| ``` |
| |
| Once you are confident the CI examples build and bundle in a container, add a |
| new job to the chef workflow. |
| |
| Replace all instances of `$PLATFORM` with the new platform. Replace `$VERSION` |
| with the image version used in the rest of the workflows, or update the image |
| version for all images in the workflow as needed. |
| |
| ```yaml |
| chef_$PLATFORM: |
| name: Chef - $PLATFORM CI Examples |
| runs-on: ubuntu-latest |
| if: github.actor != 'restyled-io[bot]' |
| |
| container: |
| image: ghcr.io/project-chip/chip-build-$PLATFORM:$VERSION |
| options: --user root |
| |
| steps: |
| - name: Checkout |
| uses: actions/checkout@v3 |
| - name: Checkout submodules & Bootstrap |
| uses: ./.github/actions/checkout-submodules-and-bootstrap |
| with: |
| platform: $PLATFORM |
| - name: CI Examples $PLATFORM |
| shell: bash |
| run: | |
| ./scripts/run_in_build_env.sh "./examples/chef/chef.py --ci -t $PLATFORM" |
| ``` |
| |
| ## CD |
| |
| Once CI is enabled for a platform, the platform may also be integrated into |
| `integrations/cloudbuild/`, where chef builds are defined in `chef.yaml`. See |
| the `README` in this path for more information. |
| |
| Note that the image used in `chef.yaml` is `chip-build-vscode`. See |
| `docker/images/chip-build-vscode/Dockerfile` for the source of this image. This |
| image is a combination of the individual toolchain images. Therefore, before a |
| platform is integrated into chef CD, the toolchain should be copied into |
| `chip-build-vscode` and `chef.yaml` should be updated to use the new image |
| version. |
| |
| Finally, add the new platform to `cd_platforms` in `cicd_config.json`. The |
| configuration should follow the following schema: |
| |
| ```json |
| "$PLATFORM": { |
| "output_archive_prefix_1": ["option_1", "option_2"], |
| "output_archive_prefix_2": [], |
| } |
| ``` |
| |
| Take note of the configuration for `linux`: |
| |
| ```json |
| "linux": { |
| "linux_x86": ["--cpu_type", "x64"], |
| "linux_arm64_ipv6only": ["--cpu_type", "arm64", "--ipv6only"] |
| }, |
| ``` |
| |
| This will produce output archives prefixed `linux_x86` and |
| `linux_arm_64_ipv6only` and will append the respective options to each build |
| command for these targets. |
| |
| To test your configuration locally, you may employ a similar strategy as in CI: |
| |
| ```shell |
| docker run -it --mount source=$(pwd),target=/workspace,type=bind ghcr.io/project-chip/chip-build-vscode:$VERSION |
| ``` |
| |
| In the container: |
| |
| ```shell |
| chown -R $(whoami) /workspace |
| cd /workspace |
| source ./scripts/bootstrap.sh |
| source ./scripts/activate.sh |
| ./examples/chef/chef.py --build_all --keep_going |
| ``` |
| |
| You may also use the Google Cloud Build local builder as detailed in the |
| `README` of `integrations/cloudbuild/`. |
| |
| ## Adding new devices |
| |
| To add new devices for chef: |
| |
| - Execute `python sample_app_util.py zap <zap_file> --rename-file` to rename |
| the example and place the new file in `examples/chef/devices`. |
| - See the `README` in `examples/chef/sample_app_util/` for more info. |
| - Execute `scripts/tools/zap_regen_all.py`, commit `zzz_generated` and |
| `examples/chef/devices`. |
| - This is gated by the workflow in `.github/workflows/zap_templates.yaml`. |
| - All devices added to the repository are built in CD. |
| |
| ## Manufacturer Extensions / Custom Clusters |
| |
| You may add vendor-defined features to chef. The |
| `rootnode_onofflight_meisample*` device showcases its usage by using the Sample |
| MEI cluster which is defined on |
| `src/app/zap-templates/zcl/data-model/chip/sample-mei-cluster.xml` |
| |
| This cluster has |
| |
| - One boolean attribute: `flip-flop` |
| - A `ping` command with no arguments |
| - A command/response pair `add-arguments`. The command takes two uint8 |
| arguments and the response command returns their sum. |
| |
| You may test the `Sample MEI` via chip-tool using the following commands: |
| |
| ``` |
| # commissioning of on-network chef device |
| chip-tool pairing onnetwork 1 20202021 |
| # tests command to sum arguments: returns 30 |
| chip-tool samplemei add-arguments 1 1 10 20 |
| # sets Flip-Flop to false |
| chip-tool samplemei write flip-flop 0 1 1 |
| # reads Flip-Flop |
| chip-tool samplemei read flip-flop 1 1 |
| ``` |