# Controller

This example creates a Matter Controller using the ESP Matter data model.


See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware.

## 1. Additional Environment Setup

No additional setup is required.

## 2. Controller Example

See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/controller.html) for more information
about pairing and controlling an end-device using this example.

## 3. Controller in Rainmaker Fabric

Matter Controller in Rainmaker Fabric is available in [RainMaker Matter Examples](https://github.com/espressif/esp-rainmaker/tree/master/examples/matter).

Two different controller types are provided in RainMaker repository:

- [Matter Server-based Controller](https://github.com/espressif/esp-rainmaker/tree/master/examples/matter/matter_controller): The controller is set up with a Matter server instance. So it can be commissioned to Matter fabric with standard Matter commissioning flow. Then the NOC will be updated to controller's NOC during controller setting up.
- [Matter client-only Controller](https://github.com/espressif/esp-rainmaker/tree/master/examples/matter/client_only_matter_controller): The controller is a client-only Controller. It doesn't have standard Matter data model. And it uses RainMaker provisioning to join a Wi-Fi network.

## 4. OpenThread Border Router (OTBR) feature

### 4.1 Hardware Platform

See the [docs](https://github.com/espressif/esp-thread-br#hardware-platforms) for more information about the hardware platform.

### 4.2 Build

The sdkconfig file `sdkconfig.defaults.otbr` is provided to enable the OTBR feature on the controller.
Build and flash the controller example with the sdkconfig file 'sdkconfig.defaults.otbr'

```
idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults.otbr" set-target esp32s3 build
idf.py -p <PORT> erase-flash flash monitor
```

*Notes*: The Thread Border Router DevKit Board uses USB port.

### 4.3 Pair and Control

- Connect the controller to Wi-Fi network with the device console

```
matter esp wifi connect {ssid} {password}
```

- Initializing a new Thread network dataset and commit it as the active one

```
matter esp ot_cli dataset init new
matter esp ot_cli dataset commit active
```

- Getting the operational dataset TLV-encoded string. The `<dataset_tlvs>` will be printed.

```
matter esp ot_cli dataset active -x
```

- Starting the Thread network

```
matter esp ot_cli ifconfig up
matter esp ot_cli thread start
```

- Pairing the Thread end-device

```
matter esp controller pairing ble-thread 1234 <dataset_tlvs> 20202021 3840
```

- Control the Thread end-device on the device console (On/Off cluster Toggle command)

```
matter esp controller invoke-cmd 1234 1 6 2
```

## A1 Appendix FAQs

### A1.1 Pairing Command Failed

I cannot finish the commissioning on the controller example:

-   For onnetwork pairing, please make sure that the end-device and the controller are on the same IP-network.
-   The controller uses the hard-code test PAA certificate by default so the PAI and DAC on the end-device should be generated by the [test cert](https://github.com/espressif/connectedhomeip/blob/4f7669b052b16bd054227376e1bbadac85419793/credentials/test/attestation/Chip-Test-PAA-NoVID-Cert.pem) and the [test key](https://github.com/espressif/connectedhomeip/blob/4f7669b052b16bd054227376e1bbadac85419793/credentials/test/attestation/Chip-Test-PAA-NoVID-Key.pem)
-   If you are still facing issues, reproduce the issue on the default example for the device and then raise an [issue](https://github.com/espressif/esp-matter/issues). Make sure to share these:
    -   The complete device logs for both the devices taken over UART.
    -   The esp-matter and esp-idf branch you are using.

### A1.2 Command Send Failed

I cannot send commands to the light from the controller:

-   Make sure the pairing command was a success.
-   The command data of cluster invoking command and attribute value data of attribute writing command should be a JSON string that matches the cluster description in Matter SPEC.
-   The CASESession will be lost on end-device after reboot. But the controller will still send commands on the previous CASESession. The controller will release previous CASESession after the last command is timeout. So the second command will re-establish a new CASESession in this situation.
-   If you are still facing issues, reproduce the issue on the default example for the device and then raise an [issue](https://github.com/espressif/esp-matter/issues). Make sure to share these:
    -   The complete device logs for both the devices taken over UART.
    -   The esp-matter and esp-idf branch you are using.

### A1.3 RAM optimization
-   The `sdkconfig.defaults.ram_optimization` file is provided for RAM optimization. These configurations enable SPIRAM (CONFIG_SPIRAM=y) and allow the BSS segment to be placed in SPIRAM (CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY). With these configurations, [linker file](./main/linker.lf) can move move BSS segments of certain main controller libraries to SPIRAM. Build the example with the sdkconfig:
```
idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.defaults.ram_optimization" set-target esp32s3 build
```
-   The OTBR's sdkconfig file `sdkconfig.defaults.otbr` has RAM optimization configurations enabled by default.
-   If you encounter a crash with error message: "PSRAM chip not found or not supported, or wrong PSRAM line mode", please check whether the module has SPIRAM and if the SPIRAM mode is configured correctly:
    -   For 2MB SPIRAM, set `CONFIG_SPIRAM_MODE_QUAD=y`
    -   For SPIRAM larger than 2MB, set `CONFIG_SPIRAM_MODE_OCT=y`
-   Refer to [linker](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/optimizations.html#configuration-options-to-optimize-ram-and-flash) for other options to optimize RAM and Flash.
